0027105: Make code ISO-compliant [-Wpedantic fixes]
[occt.git] / src / GeomLib / GeomLib_Tool.cxx
CommitLineData
b311480e 1// Created on: 2003-03-18
2// Created by: Oleg FEDYAEV
973c2be1 3// Copyright (c) 2003-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 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
973c2be1 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.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
7fd59977 16
42cf5bc1 17#include <ElCLib.hxx>
18#include <ElSLib.hxx>
19#include <Extrema_ExtPC.hxx>
20#include <Extrema_ExtPC2d.hxx>
21#include <Extrema_ExtPS.hxx>
22#include <Geom2d_BezierCurve.hxx>
23#include <Geom2d_BSplineCurve.hxx>
24#include <Geom2d_Circle.hxx>
25#include <Geom2d_Curve.hxx>
26#include <Geom2d_Ellipse.hxx>
27#include <Geom2d_Hyperbola.hxx>
28#include <Geom2d_Line.hxx>
29#include <Geom2d_OffsetCurve.hxx>
30#include <Geom2d_Parabola.hxx>
31#include <Geom2d_TrimmedCurve.hxx>
32#include <Geom2dAdaptor_Curve.hxx>
33#include <Geom_BezierCurve.hxx>
34#include <Geom_BezierSurface.hxx>
35#include <Geom_BSplineCurve.hxx>
36#include <Geom_BSplineSurface.hxx>
7fd59977 37#include <Geom_Circle.hxx>
42cf5bc1 38#include <Geom_ConicalSurface.hxx>
39#include <Geom_Curve.hxx>
40#include <Geom_CylindricalSurface.hxx>
7fd59977 41#include <Geom_Ellipse.hxx>
7fd59977 42#include <Geom_Hyperbola.hxx>
42cf5bc1 43#include <Geom_Line.hxx>
7fd59977 44#include <Geom_OffsetCurve.hxx>
42cf5bc1 45#include <Geom_OffsetSurface.hxx>
46#include <Geom_Parabola.hxx>
7fd59977 47#include <Geom_Plane.hxx>
7fd59977 48#include <Geom_RectangularTrimmedSurface.hxx>
42cf5bc1 49#include <Geom_SphericalSurface.hxx>
50#include <Geom_Surface.hxx>
7fd59977 51#include <Geom_SurfaceOfLinearExtrusion.hxx>
52#include <Geom_SurfaceOfRevolution.hxx>
42cf5bc1 53#include <Geom_ToroidalSurface.hxx>
54#include <Geom_TrimmedCurve.hxx>
7fd59977 55#include <GeomAdaptor_Curve.hxx>
56#include <GeomAdaptor_Surface.hxx>
42cf5bc1 57#include <GeomLib_Tool.hxx>
58#include <gp_Circ.hxx>
7fd59977 59#include <gp_Circ2d.hxx>
42cf5bc1 60#include <gp_Cone.hxx>
61#include <gp_Cylinder.hxx>
62#include <gp_Elips.hxx>
7fd59977 63#include <gp_Elips2d.hxx>
42cf5bc1 64#include <gp_Hypr.hxx>
7fd59977 65#include <gp_Hypr2d.hxx>
42cf5bc1 66#include <gp_Lin.hxx>
67#include <gp_Lin2d.hxx>
68#include <gp_Parab.hxx>
69#include <gp_Parab2d.hxx>
70#include <gp_Pln.hxx>
71#include <gp_Pnt.hxx>
72#include <gp_Pnt2d.hxx>
73#include <gp_Sphere.hxx>
74#include <gp_Torus.hxx>
75#include <gp_Vec.hxx>
7fd59977 76
77// The functions Parameter(s) are used to compute parameter(s) of point
78// on curves and surfaces. The main rule is that tested point must lied
79// on curves or surfaces otherwise the resulted parameter(s) may be wrong.
7fd59977 80// To make search process more common the tolerance value is used to define
81// the proximity of point to curve or surface. It is clear that this tolerance
82// value can't be too high to be not in conflict with previous rule.
83static const Standard_Real MAXTOLERANCEGEOM = 1.e-4;
7fd59977 84static const Standard_Real PARTOLERANCE = 1.e-9;
85
86//=======================================================================
ce77f999 87//function : Parameter
88//purpose : Get parameter on curve of given point
89// return FALSE if point is far from curve than tolerance
90// or computation fails
7fd59977 91//=======================================================================
92
ce77f999 93Standard_Boolean GeomLib_Tool::Parameter(const Handle(Geom_Curve)& Curve,
94 const gp_Pnt& Point,
95 const Standard_Real Tolerance,
96 Standard_Real& U)
7fd59977 97{
ce77f999 98 if( Curve.IsNull() ) return Standard_False;
99 //
100 U = 0.;
101 Standard_Real aTol = (Tolerance < MAXTOLERANCEGEOM) ? Tolerance : MAXTOLERANCEGEOM;
102 aTol *= aTol;
103 //
104 Handle(Standard_Type) KindOfCurve = Curve->DynamicType();
7fd59977 105
ce77f999 106 // process analitical curves
107 if( KindOfCurve == STANDARD_TYPE (Geom_Line) ||
108 KindOfCurve == STANDARD_TYPE (Geom_Circle) ||
109 KindOfCurve == STANDARD_TYPE (Geom_Ellipse) ||
110 KindOfCurve == STANDARD_TYPE (Geom_Parabola) ||
111 KindOfCurve == STANDARD_TYPE (Geom_Hyperbola) )
112 {
113 Standard_Real D = 0.;
7fd59977 114
ce77f999 115 if( KindOfCurve == STANDARD_TYPE (Geom_Line) )
7fd59977 116 {
117 Handle(Geom_Line) aGL = Handle(Geom_Line)::DownCast(Curve);
7fd59977 118 gp_Lin aLin = aGL->Lin();
ce77f999 119 D = aLin.SquareDistance(Point);
120 if(D > aTol)
121 {
122 return Standard_False;
123 }
124 U = ElCLib::Parameter(aLin,Point);
7fd59977 125 }
ce77f999 126 else if( KindOfCurve == STANDARD_TYPE (Geom_Circle) )
7fd59977 127 {
128 Handle(Geom_Circle) aGC = Handle(Geom_Circle)::DownCast(Curve);
7fd59977 129 gp_Circ aCirc = aGC->Circ();
ce77f999 130 D = aCirc.SquareDistance(Point);
131 if(D > aTol)
132 {
133 return Standard_False;
134 }
135 U = ElCLib::Parameter(aCirc,Point);
7fd59977 136 }
ce77f999 137 else if( KindOfCurve == STANDARD_TYPE (Geom_Ellipse) )
7fd59977 138 {
139 Handle(Geom_Ellipse) aGE = Handle(Geom_Ellipse)::DownCast(Curve);
7fd59977 140 gp_Elips anElips = aGE->Elips();
ce77f999 141 U = ElCLib::Parameter(anElips,Point);
142 D = Point.SquareDistance(aGE->Value(U));
143 if(D > aTol)
144 {
145 return Standard_False;
146 }
7fd59977 147 }
ce77f999 148 else if( KindOfCurve == STANDARD_TYPE (Geom_Parabola) )
7fd59977 149 {
150 Handle(Geom_Parabola) aGP = Handle(Geom_Parabola)::DownCast(Curve);
7fd59977 151 gp_Parab aParab = aGP->Parab();
ce77f999 152 U = ElCLib::Parameter(aParab,Point);
153 D = Point.SquareDistance(aGP->Value(U));
154 if(D > aTol)
155 {
156 return Standard_False;
157 }
7fd59977 158 }
ce77f999 159 else if( KindOfCurve == STANDARD_TYPE (Geom_Hyperbola) )
7fd59977 160 {
161 Handle(Geom_Hyperbola) aGH = Handle(Geom_Hyperbola)::DownCast(Curve);
7fd59977 162 gp_Hypr aHypr = aGH->Hypr();
ce77f999 163 U = ElCLib::Parameter(aHypr,Point);
164 D = Point.SquareDistance(aGH->Value(U));
165 if(D > aTol)
166 {
167 return Standard_False;
168 }
7fd59977 169 }
ce77f999 170 }
7fd59977 171 // process parametrical curves
172 else if( KindOfCurve == STANDARD_TYPE (Geom_BSplineCurve) ||
ce77f999 173 KindOfCurve == STANDARD_TYPE (Geom_BezierCurve) ||
174 KindOfCurve == STANDARD_TYPE (Geom_TrimmedCurve) ||
175 KindOfCurve == STANDARD_TYPE (Geom_OffsetCurve) )
176 {
177 GeomAdaptor_Curve aGAC(Curve);
178 Extrema_ExtPC extrema(Point,aGAC);
179 if( !extrema.IsDone() ) return Standard_False;
180 Standard_Integer n = extrema.NbExt();
181 if( n <= 0 ) return Standard_False;
182 Standard_Integer i = 0, iMin = 0;
183 Standard_Real Dist2Min = 1.e+100;
184 for( i = 1; i <= n; i++ )
7fd59977 185 {
ce77f999 186 if (extrema.SquareDistance(i) < Dist2Min)
187 {
188 iMin = i;
189 Dist2Min = extrema.SquareDistance(i);
190 }
7fd59977 191 }
ce77f999 192 if( iMin != 0 && Dist2Min <= aTol ) U = (extrema.Point(iMin)).Parameter();
3eb3fdd8 193 else return Standard_False;
ce77f999 194 }
7fd59977 195 else { return Standard_False; }
ce77f999 196
7fd59977 197 return Standard_True;
198
199}
200
201//=======================================================================
202//function : Parameters
203//purpose : Get parameters on surface of given point
204// return FALSE if point is far from surface than tolerance
205// or computation fails
206//=======================================================================
207
208Standard_Boolean GeomLib_Tool::Parameters(const Handle(Geom_Surface)& Surface,
ce77f999 209 const gp_Pnt& Point,
210 const Standard_Real Tolerance,
211 Standard_Real& U,
212 Standard_Real& V)
7fd59977 213{
ce77f999 214 if( Surface.IsNull() ) return Standard_False;
215 //
7fd59977 216 U = 0.;
217 V = 0.;
ce77f999 218 Standard_Real aTol = (Tolerance < MAXTOLERANCEGEOM) ? Tolerance : MAXTOLERANCEGEOM;
219 aTol *= aTol;
220 //
7fd59977 221 Handle(Standard_Type) KindOfSurface = Surface->DynamicType();
222
223 // process analitical surfaces
224 if( KindOfSurface == STANDARD_TYPE (Geom_Plane) ||
ce77f999 225 KindOfSurface == STANDARD_TYPE (Geom_CylindricalSurface) ||
226 KindOfSurface == STANDARD_TYPE (Geom_ConicalSurface) ||
227 KindOfSurface == STANDARD_TYPE (Geom_SphericalSurface) ||
228 KindOfSurface == STANDARD_TYPE (Geom_ToroidalSurface) )
229 {
230 Standard_Real D = 0.;
7fd59977 231
ce77f999 232 if( KindOfSurface == STANDARD_TYPE (Geom_Plane) )
233 {
234 Handle(Geom_Plane) aGP = Handle(Geom_Plane)::DownCast(Surface);
235 gp_Pln aPlane = aGP->Pln();
236 D = aPlane.SquareDistance(Point);
237 if(D > aTol)
238 {
239 return Standard_False;
240 }
241 ElSLib::Parameters (aPlane,Point,U,V);
242 }
243 else if( KindOfSurface == STANDARD_TYPE (Geom_CylindricalSurface) )
244 {
245 Handle(Geom_CylindricalSurface) aGC = Handle(Geom_CylindricalSurface)::DownCast(Surface);
246 gp_Cylinder aCylinder = aGC->Cylinder();
247 ElSLib::Parameters(aCylinder,Point,U,V);
248 D = Point.SquareDistance(aGC->Value(U, V));
249 if(D > aTol)
250 {
251 return Standard_False;
252 }
7fd59977 253 }
ce77f999 254 else if( KindOfSurface == STANDARD_TYPE (Geom_ConicalSurface) )
255 {
256 Handle(Geom_ConicalSurface) aGC = Handle(Geom_ConicalSurface)::DownCast(Surface);
257 gp_Cone aCone = aGC->Cone();
258 ElSLib::Parameters(aCone,Point,U,V);
259 D = Point.SquareDistance(aGC->Value(U, V));
260 if(D > aTol)
261 {
262 return Standard_False;
263 }
264 }
265 else if( KindOfSurface == STANDARD_TYPE (Geom_SphericalSurface) )
266 {
267 Handle(Geom_SphericalSurface) aGS = Handle(Geom_SphericalSurface)::DownCast(Surface);
268 gp_Sphere aSphere = aGS->Sphere();
269 ElSLib::Parameters(aSphere,Point,U,V);
270 D = Point.SquareDistance(aGS->Value(U, V));
271 if(D > aTol)
272 {
273 return Standard_False;
274 }
275 }
276 else if( KindOfSurface == STANDARD_TYPE (Geom_ToroidalSurface) )
277 {
278 Handle(Geom_ToroidalSurface) aTS = Handle(Geom_ToroidalSurface)::DownCast(Surface);
279 gp_Torus aTorus = aTS->Torus();
280 ElSLib::Parameters(aTorus,Point,U,V);
281 D = Point.SquareDistance(aTS->Value(U, V));
282 if(D > aTol)
283 {
284 return Standard_False;
285 }
286 }
287 else return Standard_False;
288 }
7fd59977 289 // process parametrical surfaces
290 else if( KindOfSurface == STANDARD_TYPE (Geom_BSplineSurface) ||
ce77f999 291 KindOfSurface == STANDARD_TYPE (Geom_BezierSurface) ||
292 KindOfSurface == STANDARD_TYPE (Geom_RectangularTrimmedSurface) ||
293 KindOfSurface == STANDARD_TYPE (Geom_OffsetSurface) ||
294 KindOfSurface == STANDARD_TYPE (Geom_SurfaceOfLinearExtrusion) ||
295 KindOfSurface == STANDARD_TYPE (Geom_SurfaceOfRevolution) )
296 {
297 GeomAdaptor_Surface aGAS(Surface);
298 Standard_Real aTolU = PARTOLERANCE, aTolV = PARTOLERANCE;
299 Extrema_ExtPS extrema(Point,aGAS,aTolU,aTolV);
300 if( !extrema.IsDone() ) return Standard_False;
301 Standard_Integer n = extrema.NbExt();
302 if( n <= 0 ) return Standard_False;
7fd59977 303
ce77f999 304 Standard_Real Dist2Min = 1.e+100;
305 Standard_Integer i = 0, iMin = 0;
306 for( i = 1; i <= n; i++ )
307 {
308 if( extrema.SquareDistance(i) < Dist2Min )
309 {
310 Dist2Min = extrema.SquareDistance(i);
311 iMin = i;
312 }
7fd59977 313 }
ce77f999 314 if( iMin != 0 && Dist2Min <= aTol) extrema.Point(iMin).Parameter(U,V);
315 else return Standard_False;
316 }
7fd59977 317 else { return Standard_False; }
ce77f999 318
7fd59977 319 return Standard_True;
320
321}
322
323//=======================================================================
ce77f999 324//function : Parameter
325//purpose : Get parameter on curve of given point
326// return FALSE if point is far from curve than tolerance
327// or computation fails
7fd59977 328//=======================================================================
329
ce77f999 330Standard_Boolean GeomLib_Tool::Parameter(const Handle(Geom2d_Curve)& Curve,
331 const gp_Pnt2d& Point,
332 const Standard_Real Tolerance,
333 Standard_Real& U)
7fd59977 334{
ce77f999 335 if( Curve.IsNull() ) return Standard_False;
336 //
337 U = 0.;
338 Standard_Real aTol = (Tolerance < MAXTOLERANCEGEOM) ? Tolerance : MAXTOLERANCEGEOM;
339 aTol *= aTol;
340
7fd59977 341 Handle(Standard_Type) KindOfCurve = Curve->DynamicType();
ce77f999 342
343 // process analytical curves
344 if( KindOfCurve == STANDARD_TYPE (Geom2d_Line) ||
345 KindOfCurve == STANDARD_TYPE (Geom2d_Circle) ||
346 KindOfCurve == STANDARD_TYPE (Geom2d_Ellipse) ||
347 KindOfCurve == STANDARD_TYPE (Geom2d_Parabola) ||
348 KindOfCurve == STANDARD_TYPE (Geom2d_Hyperbola) )
349 {
350 Standard_Real D = 0.;
351
352 if( KindOfCurve == STANDARD_TYPE (Geom2d_Line) )
7fd59977 353 {
354 Handle(Geom2d_Line) aGL = Handle(Geom2d_Line)::DownCast(Curve);
7fd59977 355 gp_Lin2d aLin = aGL->Lin2d();
ce77f999 356 D = aLin.SquareDistance(Point);
357 if(D > aTol)
358 {
359 return Standard_False;
360 }
361 U = ElCLib::Parameter(aLin,Point);
7fd59977 362 }
ce77f999 363 else if( KindOfCurve == STANDARD_TYPE (Geom2d_Circle) )
7fd59977 364 {
365 Handle(Geom2d_Circle) aGC = Handle(Geom2d_Circle)::DownCast(Curve);
7fd59977 366 gp_Circ2d aCirc = aGC->Circ2d();
ce77f999 367 D = aCirc.SquareDistance(Point);
368 if(D > aTol)
369 {
370 return Standard_False;
371 }
372 U = ElCLib::Parameter(aCirc,Point);
7fd59977 373 }
ce77f999 374 else if( KindOfCurve == STANDARD_TYPE (Geom2d_Ellipse) )
7fd59977 375 {
376 Handle(Geom2d_Ellipse) aGE = Handle(Geom2d_Ellipse)::DownCast(Curve);
7fd59977 377 gp_Elips2d anElips = aGE->Elips2d();
ce77f999 378 U = ElCLib::Parameter(anElips,Point);
379 D = Point.SquareDistance(aGE->Value(U));
380 if(D > aTol)
381 {
382 return Standard_False;
383 }
7fd59977 384 }
ce77f999 385 else if( KindOfCurve == STANDARD_TYPE (Geom2d_Parabola) )
386 {
7fd59977 387 Handle(Geom2d_Parabola) aGP = Handle(Geom2d_Parabola)::DownCast(Curve);
7fd59977 388 gp_Parab2d aParab = aGP->Parab2d();
ce77f999 389 U = ElCLib::Parameter(aParab,Point);
390 D = Point.SquareDistance(aGP->Value(U));
391 if(D > aTol)
392 {
393 return Standard_False;
394 }
7fd59977 395 }
ce77f999 396 else if( KindOfCurve == STANDARD_TYPE (Geom2d_Hyperbola) )
7fd59977 397 {
398 Handle(Geom2d_Hyperbola) aGH = Handle(Geom2d_Hyperbola)::DownCast(Curve);
7fd59977 399 gp_Hypr2d aHypr = aGH->Hypr2d();
ce77f999 400 U = ElCLib::Parameter(aHypr,Point);
401 D = Point.SquareDistance(aGH->Value(U));
402 if(D > aTol)
403 {
404 return Standard_False;
405 }
7fd59977 406 }
ce77f999 407 else return Standard_False;
408 }
7fd59977 409 // process parametrical curves
410 else if( KindOfCurve == STANDARD_TYPE (Geom2d_BSplineCurve) ||
ce77f999 411 KindOfCurve == STANDARD_TYPE (Geom2d_BezierCurve) ||
412 KindOfCurve == STANDARD_TYPE (Geom2d_TrimmedCurve) ||
413 KindOfCurve == STANDARD_TYPE (Geom2d_OffsetCurve) )
414 {
415 Geom2dAdaptor_Curve aGAC(Curve);
416 Extrema_ExtPC2d extrema(Point,aGAC);
417 if( !extrema.IsDone() ) return Standard_False;
418 Standard_Integer n = extrema.NbExt();
419 if( n <= 0 ) return Standard_False;
420 Standard_Integer i = 0, iMin = 0;
421 Standard_Real Dist2Min = 1.e+100;
422 for ( i = 1; i <= n; i++ )
7fd59977 423 {
ce77f999 424 if( extrema.SquareDistance(i) < Dist2Min )
425 {
426 Dist2Min = extrema.SquareDistance(i);
427 iMin = i;
428 }
7fd59977 429 }
ce77f999 430 if( iMin != 0 && Dist2Min <= aTol ) U = (extrema.Point(iMin)).Parameter();
431 else return Standard_False;
432 }
7fd59977 433 else { return Standard_False; }
ce77f999 434
7fd59977 435 return Standard_True;
436}