]> OCCT Git - occt.git/commitdiff
0027110: Regression: Draw command "parameters" can not compute parameter on the line.
authorifv <ifv@opencascade.com>
Tue, 26 Jan 2016 13:56:23 +0000 (16:56 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 4 Feb 2016 10:29:29 +0000 (13:29 +0300)
Useless variable MAXTOLERANCEGEOM is removed in order to allow to place point at any distance from curve/surface.
Algorithm is simplified: particular calculations for analytical geometry are removed, only using of Extrema_... is kept.

Test case for issue #27110

src/GeomLib/GeomLib_Tool.cxx
src/GeomLib/GeomLib_Tool.hxx
tests/bugs/modalg_6/bug27110 [new file with mode: 0644]

index daa44083f3bc2a292f43413077c29d1def1d2801..4996027d3ee0ed032cb183828b67b8a682fd7cd9 100644 (file)
 // The functions Parameter(s) are used to compute parameter(s) of point
 // on curves and surfaces. The main rule is that tested point must lied
 // on curves or surfaces otherwise the resulted parameter(s) may be wrong.
-// To make search process more common the tolerance value is used to define
-// the proximity of point to curve or surface. It is clear that this tolerance
+// To make search process more common the MaxDist value is used to define
+// the proximity of point to curve or surface. It is clear that this MaxDist
 // value can't be too high to be not in conflict with previous rule.
-static const Standard_Real MAXTOLERANCEGEOM = 1.e-4;
 static const Standard_Real PARTOLERANCE = 1.e-9;
 
 //=======================================================================
 //function : Parameter
 //purpose  : Get parameter on curve of given point
-//           return FALSE if point is far from curve than tolerance
+//           return FALSE if point is far from curve than MaxDist
 //           or computation fails
 //=======================================================================
 
 Standard_Boolean GeomLib_Tool::Parameter(const Handle(Geom_Curve)& Curve,
                                          const gp_Pnt&             Point,
-                                         const Standard_Real       Tolerance,
+                                         const Standard_Real       MaxDist,
                                                Standard_Real&            U)
 {
   if( Curve.IsNull() ) return Standard_False;
   //
   U = 0.;
-  Standard_Real aTol = (Tolerance < MAXTOLERANCEGEOM) ? Tolerance : MAXTOLERANCEGEOM;
-  aTol *= aTol;
+  Standard_Real aTol = MaxDist * MaxDist;
   //
-  Handle(Standard_Type) KindOfCurve = Curve->DynamicType();
-
-  // process analitical curves
-  if( KindOfCurve == STANDARD_TYPE (Geom_Line) ||
-    KindOfCurve == STANDARD_TYPE (Geom_Circle) ||
-    KindOfCurve == STANDARD_TYPE (Geom_Ellipse) ||
-    KindOfCurve == STANDARD_TYPE (Geom_Parabola) ||
-    KindOfCurve == STANDARD_TYPE (Geom_Hyperbola) )
+  GeomAdaptor_Curve aGAC(Curve);
+  Extrema_ExtPC extrema(Point,aGAC);
+  //
+  if( !extrema.IsDone() ) return Standard_False;
+  //
+  Standard_Integer n = extrema.NbExt();
+  if( n <= 0 ) return Standard_False;
+  //
+  Standard_Integer i = 0, iMin = 0;
+  Standard_Real Dist2Min = RealLast();
+  for( i = 1; i <= n; i++ )
   {
-    Standard_Real D = 0.;
-
-    if( KindOfCurve == STANDARD_TYPE (Geom_Line) )
-    {
-      Handle(Geom_Line) aGL = Handle(Geom_Line)::DownCast(Curve);
-      gp_Lin aLin = aGL->Lin();
-      D = aLin.SquareDistance(Point);
-      if(D > aTol)
-      {
-        return Standard_False;
-      }
-      U = ElCLib::Parameter(aLin,Point);
-    }
-    else if( KindOfCurve == STANDARD_TYPE (Geom_Circle) )
+    if (extrema.SquareDistance(i) < Dist2Min)
     {
-      Handle(Geom_Circle) aGC = Handle(Geom_Circle)::DownCast(Curve);
-      gp_Circ aCirc = aGC->Circ();
-      D = aCirc.SquareDistance(Point);
-      if(D > aTol)
-      {
-        return Standard_False;
-      }
-      U = ElCLib::Parameter(aCirc,Point);
-    }
-    else if( KindOfCurve == STANDARD_TYPE (Geom_Ellipse) )
-    {
-      Handle(Geom_Ellipse) aGE = Handle(Geom_Ellipse)::DownCast(Curve);
-      gp_Elips anElips = aGE->Elips();
-      U = ElCLib::Parameter(anElips,Point);
-      D = Point.SquareDistance(aGE->Value(U));
-      if(D > aTol)
-      {
-        return Standard_False;
-      }
-    }
-    else if( KindOfCurve == STANDARD_TYPE (Geom_Parabola) )
-    { 
-      Handle(Geom_Parabola) aGP = Handle(Geom_Parabola)::DownCast(Curve);
-      gp_Parab aParab = aGP->Parab();
-      U = ElCLib::Parameter(aParab,Point);
-      D = Point.SquareDistance(aGP->Value(U));
-      if(D > aTol)
-      {
-        return Standard_False;
-      }
-    }
-    else if( KindOfCurve == STANDARD_TYPE (Geom_Hyperbola) )
-    {
-      Handle(Geom_Hyperbola) aGH = Handle(Geom_Hyperbola)::DownCast(Curve);
-      gp_Hypr aHypr = aGH->Hypr();
-      U = ElCLib::Parameter(aHypr,Point);
-      D = Point.SquareDistance(aGH->Value(U));
-      if(D > aTol)
-      {
-        return Standard_False;
-      }
+      iMin = i;
+      Dist2Min = extrema.SquareDistance(i);
     }
   }
-  // process parametrical curves
-  else if( KindOfCurve == STANDARD_TYPE (Geom_BSplineCurve) ||
-    KindOfCurve == STANDARD_TYPE (Geom_BezierCurve) ||
-    KindOfCurve == STANDARD_TYPE (Geom_TrimmedCurve) ||
-    KindOfCurve == STANDARD_TYPE (Geom_OffsetCurve) )
+  if( iMin != 0 && Dist2Min <= aTol ) 
   {
-    GeomAdaptor_Curve aGAC(Curve);
-    Extrema_ExtPC extrema(Point,aGAC);
-    if( !extrema.IsDone() ) return Standard_False;
-    Standard_Integer n = extrema.NbExt();
-    if( n <= 0 ) return Standard_False;
-    Standard_Integer i = 0, iMin = 0;
-    Standard_Real Dist2Min = 1.e+100;
-    for( i = 1; i <= n; i++ )
-    {
-      if (extrema.SquareDistance(i) < Dist2Min)
-      {
-        iMin = i;
-        Dist2Min = extrema.SquareDistance(i);
-      }
-    }
-    if( iMin != 0 && Dist2Min <= aTol ) U = (extrema.Point(iMin)).Parameter();
-    else return Standard_False;
+    U = (extrema.Point(iMin)).Parameter();
   }
-  else { return Standard_False; }
-
+  else 
+  {
+    return Standard_False;
+  }
   return Standard_True;
 
 }
@@ -201,13 +133,13 @@ Standard_Boolean GeomLib_Tool::Parameter(const Handle(Geom_Curve)& Curve,
 //=======================================================================
 //function : Parameters
 //purpose  : Get parameters on surface of given point
-//           return FALSE if point is far from surface than tolerance
+//           return FALSE if point is far from surface than MaxDist
 //           or computation fails
 //=======================================================================
 
 Standard_Boolean GeomLib_Tool::Parameters(const Handle(Geom_Surface)& Surface,
                                           const gp_Pnt&               Point,
-                                          const Standard_Real         Tolerance,
+                                          const Standard_Real         MaxDist,
                                                 Standard_Real&              U,
                                                 Standard_Real&              V)
 {
@@ -215,106 +147,36 @@ Standard_Boolean GeomLib_Tool::Parameters(const Handle(Geom_Surface)& Surface,
   //
   U = 0.;
   V = 0.;
-  Standard_Real aTol = (Tolerance < MAXTOLERANCEGEOM) ? Tolerance : MAXTOLERANCEGEOM;
-  aTol *= aTol;
+  Standard_Real aTol = MaxDist * MaxDist;
   //
-  Handle(Standard_Type) KindOfSurface = Surface->DynamicType();
-
-  // process analitical surfaces
-  if( KindOfSurface == STANDARD_TYPE (Geom_Plane) ||
-    KindOfSurface == STANDARD_TYPE (Geom_CylindricalSurface) ||
-    KindOfSurface == STANDARD_TYPE (Geom_ConicalSurface) ||
-    KindOfSurface == STANDARD_TYPE (Geom_SphericalSurface) ||
-    KindOfSurface == STANDARD_TYPE (Geom_ToroidalSurface) )
+  GeomAdaptor_Surface aGAS(Surface);
+  Standard_Real aTolU = PARTOLERANCE, aTolV = PARTOLERANCE;
+  //
+  Extrema_ExtPS extrema(Point,aGAS,aTolU,aTolV);
+  //
+  if( !extrema.IsDone() ) return Standard_False;
+  //
+  Standard_Integer n = extrema.NbExt();
+  if( n <= 0 ) return Standard_False;
+  //
+  Standard_Real Dist2Min = RealLast();
+  Standard_Integer i = 0, iMin = 0;
+  for( i = 1; i <= n; i++ )
   {
-    Standard_Real D = 0.;
-
-    if( KindOfSurface == STANDARD_TYPE (Geom_Plane) )
-    {
-      Handle(Geom_Plane) aGP = Handle(Geom_Plane)::DownCast(Surface);
-      gp_Pln aPlane = aGP->Pln(); 
-      D = aPlane.SquareDistance(Point);
-      if(D > aTol)
-      {
-        return Standard_False;
-      }
-      ElSLib::Parameters (aPlane,Point,U,V);
-    }
-    else if( KindOfSurface == STANDARD_TYPE (Geom_CylindricalSurface) )
-    {
-      Handle(Geom_CylindricalSurface) aGC = Handle(Geom_CylindricalSurface)::DownCast(Surface);
-      gp_Cylinder aCylinder = aGC->Cylinder();
-      ElSLib::Parameters(aCylinder,Point,U,V);
-      D = Point.SquareDistance(aGC->Value(U, V));
-      if(D > aTol)
-      {
-        return Standard_False;
-      }
-    }
-    else if( KindOfSurface == STANDARD_TYPE (Geom_ConicalSurface) )
-    {
-      Handle(Geom_ConicalSurface) aGC = Handle(Geom_ConicalSurface)::DownCast(Surface);
-      gp_Cone aCone = aGC->Cone();
-      ElSLib::Parameters(aCone,Point,U,V);
-      D = Point.SquareDistance(aGC->Value(U, V));
-      if(D > aTol)
-      {
-        return Standard_False;
-      }
-    }
-    else if( KindOfSurface == STANDARD_TYPE (Geom_SphericalSurface) )
+    if( extrema.SquareDistance(i) < Dist2Min )
     {
-      Handle(Geom_SphericalSurface) aGS = Handle(Geom_SphericalSurface)::DownCast(Surface);
-      gp_Sphere aSphere = aGS->Sphere(); 
-      ElSLib::Parameters(aSphere,Point,U,V);
-      D = Point.SquareDistance(aGS->Value(U, V));
-      if(D > aTol)
-      {
-        return Standard_False;
-      }
+      Dist2Min = extrema.SquareDistance(i);
+      iMin = i;
     }
-    else if( KindOfSurface == STANDARD_TYPE (Geom_ToroidalSurface) )
-    {
-      Handle(Geom_ToroidalSurface) aTS = Handle(Geom_ToroidalSurface)::DownCast(Surface);
-      gp_Torus aTorus = aTS->Torus();
-      ElSLib::Parameters(aTorus,Point,U,V);
-      D = Point.SquareDistance(aTS->Value(U, V));
-      if(D > aTol)
-      {
-        return Standard_False;
-      }
-    }
-    else return Standard_False;
   }
-  // process parametrical surfaces
-  else if( KindOfSurface == STANDARD_TYPE (Geom_BSplineSurface) ||
-    KindOfSurface == STANDARD_TYPE (Geom_BezierSurface) ||
-    KindOfSurface == STANDARD_TYPE (Geom_RectangularTrimmedSurface) ||
-    KindOfSurface == STANDARD_TYPE (Geom_OffsetSurface) ||
-    KindOfSurface == STANDARD_TYPE (Geom_SurfaceOfLinearExtrusion) ||
-    KindOfSurface == STANDARD_TYPE (Geom_SurfaceOfRevolution) )
+  if( iMin != 0 && Dist2Min <= aTol)
   {
-    GeomAdaptor_Surface aGAS(Surface);
-    Standard_Real aTolU = PARTOLERANCE, aTolV = PARTOLERANCE;
-    Extrema_ExtPS extrema(Point,aGAS,aTolU,aTolV);
-    if( !extrema.IsDone() ) return Standard_False;
-    Standard_Integer n = extrema.NbExt();
-    if( n <= 0 ) return Standard_False;
-
-    Standard_Real Dist2Min = 1.e+100;
-    Standard_Integer i = 0, iMin = 0;
-    for( i = 1; i <= n; i++ )
-    {
-      if( extrema.SquareDistance(i) < Dist2Min )
-      {
-        Dist2Min = extrema.SquareDistance(i);
-        iMin = i;
-      }
-    }
-    if( iMin != 0 && Dist2Min <= aTol) extrema.Point(iMin).Parameter(U,V);
-    else return Standard_False;
+    extrema.Point(iMin).Parameter(U,V);
+  }
+  else
+  {
+    return Standard_False;
   }
-  else { return Standard_False; }
 
   return Standard_True;
 
@@ -323,114 +185,43 @@ Standard_Boolean GeomLib_Tool::Parameters(const Handle(Geom_Surface)& Surface,
 //=======================================================================
 //function : Parameter
 //purpose  : Get parameter on curve of given point
-//           return FALSE if point is far from curve than tolerance
+//           return FALSE if point is far from curve than MaxDist
 //           or computation fails
 //=======================================================================
 
 Standard_Boolean GeomLib_Tool::Parameter(const Handle(Geom2d_Curve)& Curve,
                                          const gp_Pnt2d&             Point,
-                                         const Standard_Real         Tolerance,
+                                         const Standard_Real         MaxDist,
                                                Standard_Real&              U)
 {
   if( Curve.IsNull() ) return Standard_False;
   //
   U = 0.;
-  Standard_Real aTol = (Tolerance < MAXTOLERANCEGEOM) ? Tolerance : MAXTOLERANCEGEOM;
-  aTol *= aTol;
-
-  Handle(Standard_Type) KindOfCurve = Curve->DynamicType();
-
-  // process analytical curves
-  if( KindOfCurve == STANDARD_TYPE (Geom2d_Line) ||
-    KindOfCurve == STANDARD_TYPE (Geom2d_Circle) ||
-    KindOfCurve == STANDARD_TYPE (Geom2d_Ellipse) ||
-    KindOfCurve == STANDARD_TYPE (Geom2d_Parabola) ||
-    KindOfCurve == STANDARD_TYPE (Geom2d_Hyperbola) )
+  Standard_Real aTol = MaxDist * MaxDist;
+  //
+  Geom2dAdaptor_Curve aGAC(Curve);
+  Extrema_ExtPC2d extrema(Point,aGAC);
+  if( !extrema.IsDone() ) return Standard_False;
+  Standard_Integer n = extrema.NbExt();
+  if( n <= 0 ) return Standard_False;
+  Standard_Integer i = 0, iMin = 0;
+  Standard_Real Dist2Min = RealLast();
+  for ( i = 1; i <= n; i++ )
   {
-    Standard_Real D = 0.;
-
-    if( KindOfCurve == STANDARD_TYPE (Geom2d_Line) )
-    {
-      Handle(Geom2d_Line) aGL = Handle(Geom2d_Line)::DownCast(Curve);
-      gp_Lin2d aLin = aGL->Lin2d();
-      D = aLin.SquareDistance(Point);
-      if(D > aTol)
-      {
-        return Standard_False;
-      }
-      U = ElCLib::Parameter(aLin,Point);
-    }
-    else if( KindOfCurve == STANDARD_TYPE (Geom2d_Circle) )
-    {
-      Handle(Geom2d_Circle) aGC = Handle(Geom2d_Circle)::DownCast(Curve);
-      gp_Circ2d aCirc = aGC->Circ2d();
-      D = aCirc.SquareDistance(Point);
-      if(D > aTol)
-      {
-        return Standard_False;
-      }   
-      U = ElCLib::Parameter(aCirc,Point);
-    }
-    else if( KindOfCurve == STANDARD_TYPE (Geom2d_Ellipse) )
-    {
-      Handle(Geom2d_Ellipse) aGE = Handle(Geom2d_Ellipse)::DownCast(Curve);
-      gp_Elips2d anElips = aGE->Elips2d();
-      U = ElCLib::Parameter(anElips,Point);
-      D = Point.SquareDistance(aGE->Value(U));
-      if(D > aTol)
-      {
-        return Standard_False;
-      }   
-    }
-    else if( KindOfCurve == STANDARD_TYPE (Geom2d_Parabola) )
+    if( extrema.SquareDistance(i) < Dist2Min )
     {
-      Handle(Geom2d_Parabola) aGP = Handle(Geom2d_Parabola)::DownCast(Curve);
-      gp_Parab2d aParab = aGP->Parab2d();
-      U = ElCLib::Parameter(aParab,Point);
-      D = Point.SquareDistance(aGP->Value(U));
-      if(D > aTol)
-      {
-        return Standard_False;
-      }   
+      Dist2Min = extrema.SquareDistance(i);
+      iMin = i;
     }
-    else if( KindOfCurve == STANDARD_TYPE (Geom2d_Hyperbola) )
-    {
-      Handle(Geom2d_Hyperbola) aGH = Handle(Geom2d_Hyperbola)::DownCast(Curve);
-      gp_Hypr2d aHypr = aGH->Hypr2d();
-      U = ElCLib::Parameter(aHypr,Point);
-      D = Point.SquareDistance(aGH->Value(U));
-      if(D > aTol)
-      {
-        return Standard_False;
-      }   
-    }
-    else return Standard_False;
   }
-  // process parametrical curves
-  else if( KindOfCurve == STANDARD_TYPE (Geom2d_BSplineCurve) ||
-    KindOfCurve == STANDARD_TYPE (Geom2d_BezierCurve) ||
-    KindOfCurve == STANDARD_TYPE (Geom2d_TrimmedCurve) ||
-    KindOfCurve == STANDARD_TYPE (Geom2d_OffsetCurve) )
+  if( iMin != 0 && Dist2Min <= aTol )
   {
-    Geom2dAdaptor_Curve aGAC(Curve);
-    Extrema_ExtPC2d extrema(Point,aGAC);
-    if( !extrema.IsDone() ) return Standard_False;
-    Standard_Integer n = extrema.NbExt();
-    if( n <= 0 ) return Standard_False;
-    Standard_Integer i = 0, iMin = 0;
-    Standard_Real Dist2Min = 1.e+100;
-    for ( i = 1; i <= n; i++ )
-    {
-      if( extrema.SquareDistance(i) < Dist2Min )
-      {
-        Dist2Min = extrema.SquareDistance(i);
-        iMin = i;
-      }
-    }
-    if( iMin != 0 && Dist2Min <= aTol ) U = (extrema.Point(iMin)).Parameter();
-    else return Standard_False;
+    U = (extrema.Point(iMin)).Parameter();
+  }
+  else
+  {
+    return Standard_False;
   }
-  else { return Standard_False; }
 
   return Standard_True;
 }
index adde730f8836d38787cdc661889a78f016093a46..5746a6d155e7aca9de7c282b5b5a8e1875103dc3 100644 (file)
@@ -31,14 +31,13 @@ class gp_Pnt2d;
 
 //! Provides various methods with Geom2d and Geom curves and surfaces.
 //! The methods of this class compute the parameter(s) of a given point on a
-//! curve or a surface. The point must be located either
-//! on the curve (surface) itself or relatively to the latter at
-//! a distance less than the tolerance value.
-//! Return FALSE if the point is beyond the tolerance
+//! curve or a surface. To get the valid result the point must be located rather close 
+//! to the curve (surface) or at least to allow getting unambiguous result
+//! (do not put point at center of circle...),
+//! but choice of "trust" distance between curve/surface and point is 
+//! responcibility of user (parameter MaxDist).
+//! Return FALSE if the point is beyond the MaxDist
 //! limit or if computation fails.
-//! Max Tolerance value is currently limited to 1.e-4 for
-//! geometrical curves and 1.e-3 for BSpline, Bezier and
-//! other parametrical curves.
 class GeomLib_Tool 
 {
 public:
@@ -48,16 +47,16 @@ public:
   
 
   //! Extracts the parameter of a 3D point lying on a 3D curve
-  //! or at a distance less than the tolerance value.
-  Standard_EXPORT static Standard_Boolean Parameter (const Handle(Geom_Curve)& Curve, const gp_Pnt& Point, const Standard_Real Tolerance, Standard_Real& U);
+  //! or at a distance less than the MaxDist value.
+  Standard_EXPORT static Standard_Boolean Parameter (const Handle(Geom_Curve)& Curve, const gp_Pnt& Point, const Standard_Real MaxDist, Standard_Real& U);
   
   //! Extracts the parameter of a 3D point lying on a surface
-  //! or at a distance less than the tolerance value.
-  Standard_EXPORT static Standard_Boolean Parameters (const Handle(Geom_Surface)& Surface, const gp_Pnt& Point, const Standard_Real Tolerance, Standard_Real& U, Standard_Real& V);
+  //! or at a distance less than the MaxDist value.
+  Standard_EXPORT static Standard_Boolean Parameters (const Handle(Geom_Surface)& Surface, const gp_Pnt& Point, const Standard_Real MaxDist, Standard_Real& U, Standard_Real& V);
   
   //! Extracts the parameter of a 2D point lying on a 2D curve
-  //! or at a distance less than the tolerance value.
-  Standard_EXPORT static Standard_Boolean Parameter (const Handle(Geom2d_Curve)& Curve, const gp_Pnt2d& Point, const Standard_Real Tolerance, Standard_Real& U);
+  //! or at a distance less than the MaxDist value.
+  Standard_EXPORT static Standard_Boolean Parameter (const Handle(Geom2d_Curve)& Curve, const gp_Pnt2d& Point, const Standard_Real MaxDist, Standard_Real& U);
 
 
 
diff --git a/tests/bugs/modalg_6/bug27110 b/tests/bugs/modalg_6/bug27110
new file mode 100644 (file)
index 0000000..ce5a707
--- /dev/null
@@ -0,0 +1,17 @@
+puts "========"
+puts "OCC27110"
+puts "========"
+puts ""
+###############################################################################
+# Regression: Draw command "parameters" can not compute parameter on the line
+###############################################################################
+
+restore [locate_data_file bug27110-ClosedWireEdge.brep] e1
+mkcurve c1 e1
+parameters c1 800.0 0.001 0 0.001 U
+
+set bug_info [dump U]
+set bug_info [string trim [string range $bug_info [expr {[string last "\n" $bug_info] + 1}] [expr {[string length $bug_info] - 1}]]]
+if {$bug_info != 800} {
+  puts "ERROR: OCC27110 is reproduced. Parameters U is not equal 800."
+}