]> OCCT Git - occt-copy.git/commitdiff
0027110: Regression: Draw command "parameters" can not compute parameter on the line.
authorifv <ifv@opencascade.com>
Mon, 1 Feb 2016 08:02:39 +0000 (11:02 +0300)
committerifv <ifv@opencascade.com>
Mon, 1 Feb 2016 08:02:39 +0000 (11:02 +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.

src/GeomLib/GeomLib_Tool.cdl
src/GeomLib/GeomLib_Tool.cxx

index ce75c4f4b18d97978dcb27155f7f0af73111630a..b29aec08064a80c658e0223e4c6dfcf670decb5c 100644 (file)
@@ -17,14 +17,13 @@ class Tool from GeomLib
 
 ---Purpose: 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.
         
 uses Surface from Geom,
      Curve   from Geom,
@@ -36,29 +35,28 @@ uses Surface from Geom,
 is
 
     Parameter(myclass; Curve     : in Curve from Geom;
-                      Point     : in Pnt   from gp;
-                      Tolerance : in Real  from Standard;
-                      U         : out Real from Standard)
+                          Point     : in Pnt   from gp;
+                                  MaxDist   : in Real  from Standard;
+                                  U         : out Real from Standard)
      returns Boolean from Standard;
-     ---Purpose: 
--- Extracts the parameter of a 3D point lying on a 3D curve
--- or at a distance less than the tolerance value.
+     ---Purpose: Extracts the parameter of a 3D point lying on a 3D curve
+     -- or at a distance less than the MaxDist value.
      
     Parameters(myclass; Surface   : in Surface from Geom;
-                       Point     : in Pnt     from gp;
-                       Tolerance : in Real    from Standard;
-                       U         : out Real   from Standard;
-                       V         : out Real   from Standard)
+                           Point     : in Pnt     from gp;
+                           MaxDist   : in Real    from Standard;
+                           U         : out Real   from Standard;
+                             V         : out Real   from Standard)
      returns Boolean from Standard;
      ---Purpose: Extracts the parameter of a 3D point lying on a surface
--- or at a distance less than the tolerance value. 
+     -- or at a distance less than the MaxDist value. 
      
     Parameter(myclass; Curve     : in Curve from Geom2d;
-                      Point     : in Pnt2d from gp;
-                      Tolerance : in Real  from Standard;
-                      U         : out Real from Standard)
+                          Point     : in Pnt2d from gp;
+                          MaxDist   : in Real  from Standard;
+                          U         : out Real from Standard)
      returns Boolean from Standard;
      ---Purpose: Extracts the parameter of a 2D point lying on a 2D curve
--- or at a distance less than the tolerance value. 
+     -- or at a distance less than the MaxDist value. 
 
 end Tool;
index 97e149e318d451f6d727f9825c2efa5021cfae2c..f04d2e358ff61abacff10c4a9fb4f48462b3d7f8 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 MAXTOLERANCEPARM = 1.e-3;
-static const Standard_Real UNKNOWNVALUE = 1.e+100;
 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;
 
 }
@@ -205,13 +135,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)
 {
@@ -219,106 +149,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;
 
@@ -327,114 +187,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;
 }