0022848: Optimize projection of points in ShapeAnalysis_Surface
authorGKA <>
Wed, 22 Feb 2012 12:30:10 +0000 (12:30 +0000)
committerbugmaster <bugmaster@opencascade.com>
Mon, 5 Mar 2012 15:33:02 +0000 (19:33 +0400)
src/Extrema/Extrema_FuncExtPS.cdl
src/Extrema/Extrema_FuncExtPS.cxx
src/Extrema/Extrema_GenExtPS.cxx
src/ShapeAnalysis/ShapeAnalysis_Surface.cxx

index ff4042c..34ff180 100755 (executable)
 private class FuncExtPS from Extrema
 
  inherits FunctionSetWithDerivatives from math
-    ---Purpose: Function to find the extrema of the 
-    --          distance between a point and a surface.
+    ---Purpose: 
+    --
+    -- Functional for search of extremum of the distance between point P and 
+    -- surface S, starting from approximate solution (u0, v0).
+    --          
+    -- The class inherits math_FunctionSetWithDerivatives and thus is intended
+    -- for use in math_FunctionSetRoot algorithm .
+    --          
+    -- Denoting derivatives of the surface S(u,v) by u and v, respectively, as 
+    -- Su and Sv, the two functions to be nullified are:
+    --          
+    -- F1(u,v) = (S - P) * Su
+    -- F2(u,v) = (S - P) * Sv
+    --          
+    -- The derivatives of the functional are:
+    --          
+    -- Duf1(u,v) = Su^2    + (S-P) * Suu;
+    -- Dvf1(u,v) = Su * Sv + (S-P) * Suv
+    -- Duf2(u,v) = Sv * Su + (S-P) * Suv = Dvf1
+    -- Dvf2(u,v) = Sv^2    + (S-P) * Svv
+    --
+    -- Here * denotes scalar product, and ^2 is square power. 
 
 uses    POnSurf           from Extrema,
        SequenceOfPOnSurf from Extrema,
@@ -74,13 +94,6 @@ is
        raises  OutOfRange;
                -- if N < 1 or N > NbExt(me).
 
--- Modified by skv - Thu Sep 30 15:19:59 2004 OCC593 Begin
-    HasDegIso(me) returns Boolean from Standard;
--- Modified by skv - Thu Sep 30 15:19:59 2004 OCC593 End
-
-    Bidon(me) returns SurfacePtr from Adaptor3d
-    is static private;
 fields
     myP    : Pnt from gp;
     myS    : SurfacePtr from Adaptor3d;
@@ -93,7 +106,5 @@ fields
     myPoint: SequenceOfPOnSurf from Extrema;
     myPinit: Boolean;
     mySinit: Boolean;
-    myUIsoIsDeg: Boolean;
-    myVIsoIsDeg: Boolean;
 
 end FuncExtPS;
index 16d8d36..c841bc9 100755 (executable)
 #include <Precision.hxx>
 #include <GeomAbs_IsoType.hxx>
 
-/*-----------------------------------------------------------------------------
- Fonctions permettant de rechercher une distance extremale entre un point P
-et une surface S (en partant d'un point approche S(u0,v0)).
- Cette classe herite de math_FunctionSetWithDerivatives et est utilisee par
-l'algorithme math_FunctionSetRoot.
- Si on note Dus et Dvs, les derivees en u et v, les 2 fonctions a annuler sont:
-  { F1(u,v) = (S(u,v)-P).Dus(u,v) }
-  { F2(u,v) = (S(u,v)-P).Dvs(u,v) }
- Si on note Duus, Dvvs et Duvs, les derivees secondes de S, les derivees de F1
-et F2 sont egales a:
-  { Duf1(u,v) = Dus(u,v).Dus(u,v) + (S(u,v)-P).Duus(u,v)
-              = ||Dus(u,v)|| ** 2 + (S(u,v)-P).Duus(u,v)
-  { Dvf1(u,v) = Dvs(u,v).Dus(u,v) + (S(u,v)-P).Duvs(u,v)
-  { Duf2(u,v) = Dus(u,v).Dvs(u,v) + (S(u,v)-P).Duvs(u,v) = dF1v(u,v)
-  { Dvf2(u,v) = Dvs(u,v).Dvs(u,v) + (S(u,v)-P).Dvvs(u,v)
-              = ||Dvs(u,v)|| ** 2 + (S(u,v)-P).Dvvs(u,v)
-
-----------------------------------------------------------------------------*/
-//  modified by NIZHNY-EAP Wed Nov 21 17:33:05 2001
-//  -- Dus and Dvs normalized, Df modified accordingly (BUC61043)
-//=============================================================================
-//------------------------------------------------------------------------------
-// This method checks if isocurve is punctual (for details see Geom_OffsetSurface
-// and Geom_OsculatingSurface
-//-------------------------------------------------------------------------------
-
-static Standard_Boolean IsoIsDeg  (const Adaptor3d_Surface& S,
-                                  const Standard_Real      Param,
-                                  const GeomAbs_IsoType    IT,
-                                  const Standard_Real      TolMin,
-                                  const Standard_Real      TolMax) 
-{
-    Standard_Real U1=0.,U2=0.,V1=0.,V2=0.,T;
-    Standard_Boolean Along = Standard_True;
-    U1 = S.FirstUParameter();
-    U2 = S.LastUParameter();
-    V1 = S.FirstVParameter();
-    V2 = S.LastVParameter();
-    gp_Vec D1U,D1V;
-    gp_Pnt P;
-    Standard_Real Step,D1NormMax;
-    if (IT == GeomAbs_IsoV) 
-    {
-      Step = (U2 - U1)/10;
-      D1NormMax=0.;
-      for (T=U1;T<=U2;T=T+Step) 
-      {
-        S.D1(T,Param,P,D1U,D1V);
-        D1NormMax=Max(D1NormMax,D1U.Magnitude());
-      }
-
-      if (D1NormMax >TolMax || D1NormMax < TolMin ) 
-           Along = Standard_False;
-    }
-    else 
-    {
-      Step = (V2 - V1)/10;
-      D1NormMax=0.;
-      for (T=V1;T<=V2;T=T+Step) 
-      {
-       S.D1(Param,T,P,D1U,D1V);
-        D1NormMax=Max(D1NormMax,D1V.Magnitude());
-      }
-
-      if (D1NormMax >TolMax || D1NormMax < TolMin ) 
-           Along = Standard_False;
-
-
-    }
-    return Along;
-}
-
-
 Extrema_FuncExtPS::Extrema_FuncExtPS ()
 {
   myPinit = Standard_False;
   mySinit = Standard_False;
-  myUIsoIsDeg = Standard_False;
-  myVIsoIsDeg = Standard_False;
 }
+
 //=============================================================================
 Extrema_FuncExtPS::Extrema_FuncExtPS (const gp_Pnt& P,
                                       const Adaptor3d_Surface& S)
 {
   myP = P;
   myS = (Adaptor3d_SurfacePtr)&S;
-  myUIsoIsDeg = Standard_False;
-  myVIsoIsDeg = Standard_False;
   GeomAbs_SurfaceType aSType = S.GetType();
-  if(aSType == GeomAbs_BezierSurface ||
-     aSType == GeomAbs_BSplineSurface) {
-    Standard_Real u1, u2, v1, v2;
-    Standard_Real tol = Precision::Confusion();
-    u1 = S.FirstUParameter();
-    u2 = S.LastUParameter();
-    v1 = S.FirstVParameter();
-    v2 = S.LastVParameter();
-    myUIsoIsDeg = IsoIsDeg(S, u1, GeomAbs_IsoU, 0., tol) ||
-                  IsoIsDeg(S, u2, GeomAbs_IsoU, 0., tol);
-    myVIsoIsDeg = IsoIsDeg(S, v1, GeomAbs_IsoV, 0., tol) ||
-                  IsoIsDeg(S, v2, GeomAbs_IsoV, 0., tol);
-  }
   myPinit = Standard_True;
   mySinit = Standard_True;
 }
@@ -123,22 +34,7 @@ Extrema_FuncExtPS::Extrema_FuncExtPS (const gp_Pnt& P,
 void Extrema_FuncExtPS::Initialize(const Adaptor3d_Surface& S)
 {
   myS = (Adaptor3d_SurfacePtr)&S;
-  myUIsoIsDeg = Standard_False;
-  myVIsoIsDeg = Standard_False;
   GeomAbs_SurfaceType aSType = S.GetType();
-  if(aSType == GeomAbs_BezierSurface ||
-     aSType == GeomAbs_BSplineSurface) {
-    Standard_Real u1, u2, v1, v2;
-    Standard_Real tol = Precision::Confusion();
-    u1 = S.FirstUParameter();
-    u2 = S.LastUParameter();
-    v1 = S.FirstVParameter();
-    v2 = S.LastVParameter();
-    myUIsoIsDeg = IsoIsDeg(S, u1, GeomAbs_IsoU, 0., tol) ||
-                  IsoIsDeg(S, u2, GeomAbs_IsoU, 0., tol);
-    myVIsoIsDeg = IsoIsDeg(S, v1, GeomAbs_IsoV, 0., tol) ||
-                  IsoIsDeg(S, v2, GeomAbs_IsoV, 0., tol);
-  }
   mySinit = Standard_True;
   myPoint.Clear();
   mySqDist.Clear();
@@ -174,19 +70,7 @@ Standard_Boolean Extrema_FuncExtPS::Value (const math_Vector& UV,
   myS->D1(myU,myV,myPs,Dus,Dvs);
 
   gp_Vec PPs (myP,myPs);
-  // EAP
-  if(myVIsoIsDeg)
-  {
-    Standard_Real DusMod = Dus.Magnitude();
-    if (DusMod>gp::Resolution() && DusMod<1.)
-      Dus.Multiply(1/DusMod);
-  }
-  if (myUIsoIsDeg) {
-    Standard_Real DvsMod = Dvs.Magnitude();
-    if (DvsMod>gp::Resolution() && DvsMod<1.) 
-      Dvs.Multiply(1/DvsMod);
-  }
-    
+
   F(1) = PPs.Dot(Dus);
   F(2) = PPs.Dot(Dvs);
 
@@ -213,57 +97,13 @@ Standard_Boolean Extrema_FuncExtPS::Values (const math_Vector& UV,
   myS->D2(myU,myV,myPs,Dus,Dvs,Duus,Dvvs,Duvs);
 
   gp_Vec PPs (myP,myPs);
-  // EAP
-//  Df(1,1) = Dus.SquareMagnitude() + PPs.Dot(Duus);
-//  Df(1,2) = Dvs.Dot(Dus) + PPs.Dot(Duvs);
-//  Df(2,1) = Df(1,2);
-//  Df(2,2) = Dvs.SquareMagnitude() + PPs.Dot(Dvvs);
 
-  // 25/03/02 akm : (OCC231) Further normalization of derivatives for surfaces
-  //                with singularities will hence be performed only when modulus
-  //                becomes less than 1.0. Thus the continuity will be kept,
-  //                and normalization will be switched off 'far' from singularities.
-  // 1. V iso
-  Standard_Real DusMod2 = Dus.SquareMagnitude();
-  if (myVIsoIsDeg)
-  {
-    Standard_Real DusMod = Sqrt(DusMod2);
-    if (DusMod2>gp::Resolution() && DusMod2<1.)
-    {
-      Dus.Multiply(1/DusMod);
-      Df(1,1) = DusMod2 + PPs.Dot( (Duus*DusMod - Dus*(Dus.Dot(Duus)/DusMod)) / DusMod2 );
-      Df(1,2) = Dvs.Dot(Dus) + PPs.Dot( (Duvs*DusMod-Dus*(Dus.Dot(Duvs)/DusMod)) / DusMod2 );
-    }
-    else {
-      Df(1,1) = DusMod2 + PPs.Dot(Duus);
-      Df(1,2) = Dvs.Dot(Dus) + PPs.Dot(Duvs);
-    }
-  }
-  else {
-    Df(1,1) = DusMod2 + PPs.Dot(Duus);
-    Df(1,2) = Dvs.Dot(Dus) + PPs.Dot(Duvs);
-  }
-  // 2. U iso
-  Standard_Real DvsMod2 = Dvs.SquareMagnitude();
-  if (myUIsoIsDeg)
-  {
-    Standard_Real DvsMod = Sqrt(DvsMod2);
-    if (DvsMod2>gp::Resolution() && DvsMod2<1.)
-    {
-      Dvs.Multiply(1/DvsMod);
-      Df(2,1) = Dvs.Dot(Dus) + PPs.Dot( (Duvs*DvsMod-Dvs*(Dvs.Dot(Duvs)/DvsMod)) / DvsMod2 );
-      Df(2,2) = DvsMod2 + PPs.Dot( (Duus*DvsMod - Dus*(Dus.Dot(Duus)/DvsMod)) / DvsMod2 );
-    }
-    else {
-      Df(2,1) = Dvs.Dot(Dus) + PPs.Dot(Duvs);
-      Df(2,2) = DvsMod2 + PPs.Dot(Dvvs);
-    }
-  }
-  else {
-    Df(2,1) = Dvs.Dot(Dus) + PPs.Dot(Duvs);
-    Df(2,2) = DvsMod2 + PPs.Dot(Dvvs);
-  }
+  Df(1,1) = Dus.SquareMagnitude() + PPs.Dot(Duus);
+  Df(1,2) = Dvs.Dot(Dus)          + PPs.Dot(Duvs);
+  Df(2,1) = Df(1,2);
+  Df(2,2) = Dvs.SquareMagnitude() + PPs.Dot(Dvvs);
 
+  // 3. Value
   F(1) = PPs.Dot(Dus);
   F(2) = PPs.Dot(Dvs);
 
@@ -298,11 +138,3 @@ Extrema_POnSurf Extrema_FuncExtPS::Point (const Standard_Integer N) const
   if (!myPinit || !mySinit) Standard_TypeMismatch::Raise();
   return myPoint.Value(N);
 }
-//=============================================================================
-
-//  Modified by skv - Thu Sep 30 15:21:07 2004 OCC593 Begin
-Standard_Boolean Extrema_FuncExtPS::HasDegIso() const
-{
-  return myUIsoIsDeg || myVIsoIsDeg;
-}
-//  Modified by skv - Thu Sep 30 15:21:07 2004 OCC593 End
index f20ff89..56b2118 100755 (executable)
@@ -416,9 +416,6 @@ void Extrema_GenExtPS::FindSolution(const gp_Pnt& P, const math_Vector& UV, cons
 
   Standard_Integer aNbMaxIter = 100;
 
-  if (myF.HasDegIso())
-    aNbMaxIter = 150;
-
   gp_Pnt PStart = myS->Value(UV(1), UV(2));
   Standard_Real DistStart = P.SquareDistance(PStart);
   Standard_Real DistSol = DistStart;
index 89cdbb6..8886cb5 100755 (executable)
@@ -985,6 +985,7 @@ gp_Pnt2d ShapeAnalysis_Surface::ValueOfUV(const gp_Pnt& P3D,const Standard_Real
                      dv = Min (myVDelt, SurfAdapt.VResolution (preci));
         myExtSrf = mySurf;
        Standard_Real Tol = Precision::PConfusion();
+        myExtPS.SetFlag (Extrema_ExtFlag_MIN);
        myExtPS.Initialize ( myExtSrf, uf-du, ul+du, vf-dv, vl+dv, Tol, Tol );
        myExtOK = Standard_True;
       }