0027466: The algorithm Extrema_GenLocateExtPS gives incorrect result
authormsv <msv@opencascade.com>
Wed, 4 May 2016 16:18:12 +0000 (19:18 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 19 May 2016 10:17:18 +0000 (13:17 +0300)
Euclidean distance criteria is added for local point / surface extrema.
Classes representing objective criteria are renamed to be consistent.
Local extrema usage is updated according to new behavior.
Test case is added.

Misprint correction.

19 files changed:
src/ChFi3d/ChFi3d_ChBuilder.cxx
src/Extrema/Extrema_ExtPExtS.hxx
src/Extrema/Extrema_FuncExtPS.cxx [deleted file]
src/Extrema/Extrema_FuncExtPS.hxx [deleted file]
src/Extrema/Extrema_FuncPSDist.cxx [new file with mode: 0644]
src/Extrema/Extrema_FuncPSDist.hxx [new file with mode: 0644]
src/Extrema/Extrema_FuncPSNorm.cxx [new file with mode: 0644]
src/Extrema/Extrema_FuncPSNorm.hxx [new file with mode: 0644]
src/Extrema/Extrema_GenExtPS.hxx
src/Extrema/Extrema_GenLocateExtPS.cxx
src/Extrema/Extrema_GenLocateExtPS.hxx
src/Extrema/FILES
src/IntPatch/IntPatch_ImpPrmIntersection.cxx
src/IntTools/IntTools_BeanFaceIntersector.cxx
src/IntWalk/IntWalk_PWalking.cxx
src/ProjLib/ProjLib_ComputeApproxOnPolarSurface.cxx
src/QABugs/QABugs_19.cxx
src/QABugs/QABugs_20.cxx
tests/bugs/moddata_3/bug27466 [new file with mode: 0644]

index 09abd3c..e501762 100644 (file)
@@ -1332,8 +1332,11 @@ Standard_Boolean ChFi3d_ChBuilder::PerformFirstSection
     
     Standard_Real tol = tolesp*1.e2;
 //    Standard_Real u,v;
-    Extrema_GenLocateExtPS proj1(pt1,S1->Surface(),SolDep(1),SolDep(2),tol,tol);
-    Extrema_GenLocateExtPS proj2(pt2,S2->Surface(),SolDep(3),SolDep(4),tol,tol);
+    Extrema_GenLocateExtPS proj1(S1->Surface(), tol, tol);
+    proj1.Perform(pt1, SolDep(1), SolDep(2));
+    Extrema_GenLocateExtPS proj2(S2->Surface(), tol, tol);
+    proj2.Perform(pt2, SolDep(3), SolDep(4));
+
     if( proj1.IsDone() ){
       (proj1.Point()).Parameter(SolDep(1),SolDep(2)); 
     }
@@ -1389,8 +1392,12 @@ Standard_Boolean ChFi3d_ChBuilder::PerformFirstSection
     
     Standard_Real tol = tolesp*1.e2;
 //    Standard_Real u,v;
-    Extrema_GenLocateExtPS proj1(pt1,S1->Surface(),SolDep(1),SolDep(2),tol,tol);
-    Extrema_GenLocateExtPS proj2(pt2,S2->Surface(),SolDep(3),SolDep(4),tol,tol);
+
+    Extrema_GenLocateExtPS proj1(S1->Surface(), tol, tol);
+    proj1.Perform(pt1, SolDep(1), SolDep(2));
+    Extrema_GenLocateExtPS proj2(S2->Surface(), tol, tol);
+    proj2.Perform(pt2, SolDep(3), SolDep(4));
+
     if( proj1.IsDone() ){
       (proj1.Point()).Parameter(SolDep(1),SolDep(2)); 
     }
@@ -1457,8 +1464,10 @@ Standard_Boolean ChFi3d_ChBuilder::PerformFirstSection
       
       Standard_Real tol = tolesp*1.e2;
 //      Standard_Real u,v;
-      Extrema_GenLocateExtPS proj1(pt1,S1->Surface(),SolDep(1),SolDep(2),tol,tol);
-      Extrema_GenLocateExtPS proj2(pt2,S2->Surface(),SolDep(3),SolDep(4),tol,tol);
+      Extrema_GenLocateExtPS proj1(S1->Surface(), tol, tol);
+      proj1.Perform(pt1, SolDep(1), SolDep(2));
+      Extrema_GenLocateExtPS proj2(S2->Surface(), tol, tol);
+      proj2.Perform(pt2, SolDep(3), SolDep(4));
       if( proj1.IsDone() ){
        (proj1.Point()).Parameter(SolDep(1),SolDep(2)); 
       }
@@ -1525,8 +1534,10 @@ Standard_Boolean ChFi3d_ChBuilder::PerformFirstSection
       
       Standard_Real tol = tolesp*1.e2;
 //      Standard_Real u,v;
-      Extrema_GenLocateExtPS proj1(pt1,S2->Surface(),SolDep(1),SolDep(2),tol,tol);
-      Extrema_GenLocateExtPS proj2(pt2,S1->Surface(),SolDep(3),SolDep(4),tol,tol);
+      Extrema_GenLocateExtPS proj1(S2->Surface(), tol, tol);
+      proj1.Perform(pt1, SolDep(1), SolDep(2));
+      Extrema_GenLocateExtPS proj2(S1->Surface(), tol, tol);
+      proj2.Perform(pt2, SolDep(3), SolDep(4));
       if( proj1.IsDone() ) {
        (proj1.Point()).Parameter(SolDep(1),SolDep(2)); 
       }
index 426a41c..67b50a5 100644 (file)
@@ -21,7 +21,7 @@
 #include <Standard_Type.hxx>
 
 #include <Standard_Real.hxx>
-#include <Extrema_FuncExtPS.hxx>
+#include <Extrema_FuncPSNorm.hxx>
 #include <gp_Vec.hxx>
 #include <gp_Ax2.hxx>
 #include <Extrema_GenExtPS.hxx>
@@ -98,7 +98,7 @@ private:
   Standard_Real myvinf;
   Standard_Real myvsup;
   Standard_Real mytolv;
-  Extrema_FuncExtPS myF;
+  Extrema_FuncPSNorm myF;
   Handle(Adaptor3d_HCurve) myC;
   Handle(GeomAdaptor_HSurfaceOfLinearExtrusion) myS;
   gp_Vec myDirection;
diff --git a/src/Extrema/Extrema_FuncExtPS.cxx b/src/Extrema/Extrema_FuncExtPS.cxx
deleted file mode 100644 (file)
index 9700d22..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-// Created on: 1995-07-18
-// Created by: Modelistation
-// Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-//  Modified by skv - Thu Sep 30 15:21:07 2004 OCC593
-
-#include <Adaptor3d_Surface.hxx>
-#include <Extrema_FuncExtPS.hxx>
-#include <Extrema_POnSurf.hxx>
-#include <GeomAbs_IsoType.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Vec.hxx>
-#include <math_Matrix.hxx>
-#include <Precision.hxx>
-#include <Standard_OutOfRange.hxx>
-#include <Standard_TypeMismatch.hxx>
-
-Extrema_FuncExtPS::Extrema_FuncExtPS ()
-{
-  myPinit = Standard_False;
-  mySinit = Standard_False;
-}
-
-//=============================================================================
-Extrema_FuncExtPS::Extrema_FuncExtPS (const gp_Pnt& P,
-                                      const Adaptor3d_Surface& S)
-{
-  myP = P;
-  myS = (Adaptor3d_SurfacePtr)&S;
-  myPinit = Standard_True;
-  mySinit = Standard_True;
-}
-
-//=============================================================================
-void Extrema_FuncExtPS::Initialize(const Adaptor3d_Surface& S)
-{
-  myS = (Adaptor3d_SurfacePtr)&S;
-  mySinit = Standard_True;
-  myPoint.Clear();
-  mySqDist.Clear();
-}
-
-//=============================================================================
-
-void Extrema_FuncExtPS::SetPoint(const gp_Pnt& P)
-{
-  myP = P;
-  myPinit = Standard_True;
-  myPoint.Clear();
-  mySqDist.Clear();
-}
-
-//=============================================================================
-
-//=============================================================================
-
-Standard_Integer Extrema_FuncExtPS::NbVariables () const { return 2;}
-//=============================================================================
-
-Standard_Integer Extrema_FuncExtPS::NbEquations () const { return 2;}
-//=============================================================================
-
-Standard_Boolean Extrema_FuncExtPS::Value (const math_Vector& UV, 
-                                           math_Vector& F)
-{
-  if (!myPinit || !mySinit) Standard_TypeMismatch::Raise();
-  myU = UV(1);
-  myV = UV(2);
-  gp_Vec Dus, Dvs;
-  myS->D1(myU,myV,myPs,Dus,Dvs);
-
-  gp_Vec PPs (myP,myPs);
-
-  F(1) = PPs.Dot(Dus);
-  F(2) = PPs.Dot(Dvs);
-
-  return Standard_True;
-}
-//=============================================================================
-
-Standard_Boolean Extrema_FuncExtPS::Derivatives (const math_Vector& UV, 
-                                                 math_Matrix& Df)
-{
-  math_Vector F(1,2);
-  return Values(UV,F,Df);
-}
-//=============================================================================
-
-Standard_Boolean Extrema_FuncExtPS::Values (const math_Vector& UV, 
-                                            math_Vector& F,
-                                            math_Matrix& Df)
-{
-  if (!myPinit || !mySinit) Standard_TypeMismatch::Raise();
-  myU = UV(1);
-  myV = UV(2);
-  gp_Vec Dus, Dvs, Duus, Dvvs, Duvs;
-  myS->D2(myU,myV,myPs,Dus,Dvs,Duus,Dvvs,Duvs);
-
-  gp_Vec PPs (myP,myPs);
-
-  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);
-
-  return Standard_True;
-}
-//=============================================================================
-
-Standard_Integer Extrema_FuncExtPS::GetStateNumber ()
-{
-  if (!myPinit || !mySinit) Standard_TypeMismatch::Raise();
-  //comparison of solution with previous solutions
-  Standard_Integer i = 1, nbSol = mySqDist.Length();
-  Standard_Real tol2d = Precision::PConfusion() * Precision::PConfusion();
-   
-  for( ; i <=  nbSol; i++)
-  {
-    Standard_Real aU, aV;
-       myPoint(i).Parameter(aU, aV);
-       if( ((myU - aU ) * (myU - aU ) + (myV - aV ) * (myV - aV )) <= tol2d )
-      break;
-  }
-  if( i <= nbSol)
-         return 0;
-  mySqDist.Append(myPs.SquareDistance(myP));
-  myPoint.Append(Extrema_POnSurf(myU,myV,myPs));
-  return 0;
-}
-//=============================================================================
-
-Standard_Integer Extrema_FuncExtPS::NbExt () const
-{
-  return mySqDist.Length();
-}
-//=============================================================================
-
-Standard_Real Extrema_FuncExtPS::SquareDistance (const Standard_Integer N) const
-{
-  if (!myPinit || !mySinit) Standard_TypeMismatch::Raise();
-  return mySqDist.Value(N);
-}
-//=============================================================================
-
-const Extrema_POnSurf& Extrema_FuncExtPS::Point (const Standard_Integer N) const
-{
-  if (!myPinit || !mySinit) Standard_TypeMismatch::Raise();
-  return myPoint.Value(N);
-}
diff --git a/src/Extrema/Extrema_FuncExtPS.hxx b/src/Extrema/Extrema_FuncExtPS.hxx
deleted file mode 100644 (file)
index 2dc9213..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-// Created on: 1991-07-24
-// Created by: Michel CHAUVAT
-// Copyright (c) 1991-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#ifndef _Extrema_FuncExtPS_HeaderFile
-#define _Extrema_FuncExtPS_HeaderFile
-
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
-
-#include <gp_Pnt.hxx>
-#include <Adaptor3d_SurfacePtr.hxx>
-#include <Standard_Real.hxx>
-#include <TColStd_SequenceOfReal.hxx>
-#include <Extrema_SequenceOfPOnSurf.hxx>
-#include <Standard_Boolean.hxx>
-#include <math_FunctionSetWithDerivatives.hxx>
-#include <Standard_Integer.hxx>
-#include <math_Vector.hxx>
-class Standard_OutOfRange;
-class gp_Pnt;
-class Adaptor3d_Surface;
-class math_Matrix;
-class Extrema_POnSurf;
-
-
-
-//! 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.
-class Extrema_FuncExtPS  : public math_FunctionSetWithDerivatives
-{
-public:
-
-  DEFINE_STANDARD_ALLOC
-
-  
-  Standard_EXPORT Extrema_FuncExtPS();
-  
-  Standard_EXPORT Extrema_FuncExtPS(const gp_Pnt& P, const Adaptor3d_Surface& S);
-  
-  //! sets the field mysurf of the function.
-  Standard_EXPORT void Initialize (const Adaptor3d_Surface& S);
-  
-  //! sets the field mysurf of the function.
-  Standard_EXPORT void SetPoint (const gp_Pnt& P);
-  
-  Standard_EXPORT Standard_Integer NbVariables() const Standard_OVERRIDE;
-  
-  Standard_EXPORT Standard_Integer NbEquations() const Standard_OVERRIDE;
-  
-  //! Calculate Fi(U,V).
-  Standard_EXPORT Standard_Boolean Value (const math_Vector& UV, math_Vector& F) Standard_OVERRIDE;
-  
-  //! Calculate Fi'(U,V).
-  Standard_EXPORT Standard_Boolean Derivatives (const math_Vector& UV, math_Matrix& DF) Standard_OVERRIDE;
-  
-  //! Calculate Fi(U,V) and Fi'(U,V).
-  Standard_EXPORT Standard_Boolean Values (const math_Vector& UV, math_Vector& F, math_Matrix& DF) Standard_OVERRIDE;
-  
-  //! Save the found extremum.
-  Standard_EXPORT virtual Standard_Integer GetStateNumber() Standard_OVERRIDE;
-  
-  //! Return the number of found extrema.
-  Standard_EXPORT Standard_Integer NbExt() const;
-  
-  //! Return the value of the Nth distance.
-  Standard_EXPORT Standard_Real SquareDistance (const Standard_Integer N) const;
-  
-  //! Returns the Nth extremum.
-  Standard_EXPORT const Extrema_POnSurf& Point (const Standard_Integer N) const;
-
-
-
-
-protected:
-
-
-
-
-
-private:
-
-
-
-  gp_Pnt myP;
-  Adaptor3d_SurfacePtr myS;
-  Standard_Real myU;
-  Standard_Real myV;
-  gp_Pnt myPs;
-  TColStd_SequenceOfReal mySqDist;
-  Extrema_SequenceOfPOnSurf myPoint;
-  Standard_Boolean myPinit;
-  Standard_Boolean mySinit;
-
-
-};
-
-
-
-
-
-
-
-#endif // _Extrema_FuncExtPS_HeaderFile
diff --git a/src/Extrema/Extrema_FuncPSDist.cxx b/src/Extrema/Extrema_FuncPSDist.cxx
new file mode 100644 (file)
index 0000000..e985785
--- /dev/null
@@ -0,0 +1,119 @@
+// Created on: 2016-05-10
+// Created by: Alexander MALYSHEV
+// Copyright (c) 1995-1999 Matra Datavision
+// Copyright (c) 1999-2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+
+#include <Extrema_FuncPSDist.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Vec.hxx>
+#include <math_Vector.hxx>
+
+//=======================================================================
+//function : Extrema_FuncPSDist
+//purpose  : 
+//=======================================================================
+Extrema_FuncPSDist::Extrema_FuncPSDist(const Adaptor3d_Surface& theS,
+                                       const gp_Pnt& theP)
+: mySurf(theS),
+  myP(theP)
+{
+}
+
+//=======================================================================
+//function : NbVariables
+//purpose  : 
+//=======================================================================
+Standard_Integer Extrema_FuncPSDist::NbVariables () const
+{
+  return 2;
+}
+
+//=======================================================================
+//function : Value
+//purpose  : 
+//=======================================================================
+Standard_Boolean Extrema_FuncPSDist::Value(const math_Vector& X,Standard_Real& F)
+{
+  if (!IsInside(X))
+    return Standard_False;
+
+  F = mySurf.Value(X(1), X(2)).SquareDistance(myP);
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : Gradient
+//purpose  : 
+//=======================================================================
+Standard_Boolean Extrema_FuncPSDist::Gradient(const math_Vector& X,math_Vector& G)
+
+{
+  if (!IsInside(X))
+    return Standard_False;
+
+  gp_Pnt aP;
+  gp_Vec Du1s, Dv1s;
+  mySurf.D1(X(1),X(2),aP,Du1s,Dv1s);
+
+  gp_Vec P1P2 (aP, myP);
+
+  G(1) = P1P2.Dot(Du1s);
+  G(2) = P1P2.Dot(Dv1s);
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : Values
+//purpose  : 
+//=======================================================================
+Standard_Boolean Extrema_FuncPSDist::Values(const math_Vector& X,Standard_Real& F,math_Vector& G)
+{
+  if (!IsInside(X))
+    return Standard_False;
+
+  gp_Pnt aP;
+  gp_Vec Du1s, Dv1s;
+  mySurf.D1(X(1),X(2),aP,Du1s,Dv1s);
+
+  gp_Vec P1P2 (aP, myP);
+
+  G(1) = P1P2.Dot(Du1s);
+  G(2) = P1P2.Dot(Dv1s);
+
+  F = mySurf.Value(X(1), X(2)).SquareDistance(myP);
+
+  return true;
+}
+
+//=======================================================================
+//function : IsInside
+//purpose  : 
+//=======================================================================
+Standard_Boolean Extrema_FuncPSDist::IsInside(const math_Vector& X)
+{
+    if (X(1) < mySurf.FirstUParameter() ||
+        X(1) > mySurf.LastUParameter() ||
+        X(2) < mySurf.FirstUParameter() ||
+        X(2) > mySurf.LastUParameter() )
+    {
+      // Point out of borders.
+      return Standard_False;
+    }
+
+  // Point is inside.
+  return Standard_True;
+}
diff --git a/src/Extrema/Extrema_FuncPSDist.hxx b/src/Extrema/Extrema_FuncPSDist.hxx
new file mode 100644 (file)
index 0000000..42e9d76
--- /dev/null
@@ -0,0 +1,82 @@
+// Created on: 2016-05-10
+// Created by: Alexander MALYSHEV
+// Copyright (c) 1991-1999 Matra Datavision
+// Copyright (c) 1999-2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Extrema_FuncPSDsit_HeaderFile
+#define _Extrema_FuncPSDsit_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_DefineAlloc.hxx>
+
+#include <math_MultipleVarFunctionWithGradient.hxx>
+#include <gp_Pnt.hxx>
+#include <Adaptor3d_Surface.hxx>
+
+#include <Standard_Real.hxx>
+#include <Standard_Boolean.hxx>
+#include <Standard_Integer.hxx>
+
+class math_Vector;
+
+//! Functional for search of extremum of the square Euclidean distance between point P and
+//! surface S, starting from approximate solution (u0, v0).
+//!
+//! The class inherits math_MultipleVarFunctionWithGradient and thus is intended
+//! for use in math_BFGS algorithm.
+//!
+//! The criteria is:
+//! F = SquareDist(P, S(u, v)) - > min
+//!
+//! The first derivative are:
+//! F1(u,v) = (S(u,v) - P) * Su
+//! F2(u,v) = (S(u,v) - P) * Sv
+//!
+//! Su and Sv are first derivatives of the surface, * symbol means dot product.
+class Extrema_FuncPSDist  : public math_MultipleVarFunctionWithGradient
+{
+public:
+
+  DEFINE_STANDARD_ALLOC
+
+  //! Constructor.
+  Standard_EXPORT Extrema_FuncPSDist(const Adaptor3d_Surface& theS,
+                                     const gp_Pnt& theP);
+
+  //! Number of variables.
+  Standard_EXPORT Standard_Integer NbVariables() const Standard_OVERRIDE;
+
+  //! Value.
+  Standard_EXPORT Standard_Boolean Value(const math_Vector& X,Standard_Real& F) Standard_OVERRIDE;
+
+  //! Gradient.
+  Standard_EXPORT Standard_Boolean Gradient(const math_Vector& X,math_Vector& G) Standard_OVERRIDE;
+
+  //! Value and gradient.
+  Standard_EXPORT Standard_Boolean Values(const math_Vector& X,Standard_Real& F,math_Vector& G) Standard_OVERRIDE;
+
+private:
+
+
+  //! Check point is inside of the surface parameter space.
+  //! Returns true if inside and false otherwise.
+  Standard_Boolean IsInside(const math_Vector& X);
+
+  const Extrema_FuncPSDist& operator=(const Extrema_FuncPSDist&);
+  Extrema_FuncPSDist(const Extrema_FuncPSDist&);
+
+  const Adaptor3d_Surface &mySurf;
+  const gp_Pnt &myP;
+};
+#endif // _Extrema_FuncPSDsit_HeaderFile
diff --git a/src/Extrema/Extrema_FuncPSNorm.cxx b/src/Extrema/Extrema_FuncPSNorm.cxx
new file mode 100644 (file)
index 0000000..06346cc
--- /dev/null
@@ -0,0 +1,163 @@
+// Created on: 1995-07-18
+// Created by: Modelistation
+// Copyright (c) 1995-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+
+#include <Extrema_FuncPSNorm.hxx>
+#include <Adaptor3d_Surface.hxx>
+#include <Extrema_POnSurf.hxx>
+#include <GeomAbs_IsoType.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Vec.hxx>
+#include <math_Matrix.hxx>
+#include <Precision.hxx>
+#include <Standard_TypeMismatch.hxx>
+
+Extrema_FuncPSNorm::Extrema_FuncPSNorm ()
+{
+  myPinit = Standard_False;
+  mySinit = Standard_False;
+}
+
+//=============================================================================
+Extrema_FuncPSNorm::Extrema_FuncPSNorm (const gp_Pnt& P,
+                                      const Adaptor3d_Surface& S)
+{
+  myP = P;
+  myS = (Adaptor3d_SurfacePtr)&S;
+  myPinit = Standard_True;
+  mySinit = Standard_True;
+}
+
+//=============================================================================
+void Extrema_FuncPSNorm::Initialize(const Adaptor3d_Surface& S)
+{
+  myS = (Adaptor3d_SurfacePtr)&S;
+  mySinit = Standard_True;
+  myPoint.Clear();
+  mySqDist.Clear();
+}
+
+//=============================================================================
+
+void Extrema_FuncPSNorm::SetPoint(const gp_Pnt& P)
+{
+  myP = P;
+  myPinit = Standard_True;
+  myPoint.Clear();
+  mySqDist.Clear();
+}
+
+//=============================================================================
+
+//=============================================================================
+
+Standard_Integer Extrema_FuncPSNorm::NbVariables () const { return 2;}
+//=============================================================================
+
+Standard_Integer Extrema_FuncPSNorm::NbEquations () const { return 2;}
+//=============================================================================
+
+Standard_Boolean Extrema_FuncPSNorm::Value (const math_Vector& UV, 
+                                           math_Vector& F)
+{
+  if (!myPinit || !mySinit) Standard_TypeMismatch::Raise();
+  myU = UV(1);
+  myV = UV(2);
+  gp_Vec Dus, Dvs;
+  myS->D1(myU,myV,myPs,Dus,Dvs);
+
+  gp_Vec PPs (myP,myPs);
+
+  F(1) = PPs.Dot(Dus);
+  F(2) = PPs.Dot(Dvs);
+
+  return Standard_True;
+}
+//=============================================================================
+
+Standard_Boolean Extrema_FuncPSNorm::Derivatives (const math_Vector& UV, 
+                                                 math_Matrix& Df)
+{
+  math_Vector F(1,2);
+  return Values(UV,F,Df);
+}
+//=============================================================================
+
+Standard_Boolean Extrema_FuncPSNorm::Values (const math_Vector& UV, 
+                                            math_Vector& F,
+                                            math_Matrix& Df)
+{
+  if (!myPinit || !mySinit) Standard_TypeMismatch::Raise();
+  myU = UV(1);
+  myV = UV(2);
+  gp_Vec Dus, Dvs, Duus, Dvvs, Duvs;
+  myS->D2(myU,myV,myPs,Dus,Dvs,Duus,Dvvs,Duvs);
+
+  gp_Vec PPs (myP,myPs);
+
+  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);
+
+  return Standard_True;
+}
+//=============================================================================
+
+Standard_Integer Extrema_FuncPSNorm::GetStateNumber ()
+{
+  if (!myPinit || !mySinit) Standard_TypeMismatch::Raise();
+  //comparison of solution with previous solutions
+  Standard_Integer i = 1, nbSol = mySqDist.Length();
+  Standard_Real tol2d = Precision::PConfusion() * Precision::PConfusion();
+   
+  for( ; i <=  nbSol; i++)
+  {
+    Standard_Real aU, aV;
+       myPoint(i).Parameter(aU, aV);
+       if( ((myU - aU ) * (myU - aU ) + (myV - aV ) * (myV - aV )) <= tol2d )
+      break;
+  }
+  if( i <= nbSol)
+         return 0;
+  mySqDist.Append(myPs.SquareDistance(myP));
+  myPoint.Append(Extrema_POnSurf(myU,myV,myPs));
+  return 0;
+}
+//=============================================================================
+
+Standard_Integer Extrema_FuncPSNorm::NbExt () const
+{
+  return mySqDist.Length();
+}
+//=============================================================================
+
+Standard_Real Extrema_FuncPSNorm::SquareDistance (const Standard_Integer N) const
+{
+  if (!myPinit || !mySinit) Standard_TypeMismatch::Raise();
+  return mySqDist.Value(N);
+}
+//=============================================================================
+
+const Extrema_POnSurf& Extrema_FuncPSNorm::Point (const Standard_Integer N) const
+{
+  if (!myPinit || !mySinit) Standard_TypeMismatch::Raise();
+  return myPoint.Value(N);
+}
diff --git a/src/Extrema/Extrema_FuncPSNorm.hxx b/src/Extrema/Extrema_FuncPSNorm.hxx
new file mode 100644 (file)
index 0000000..275f0f2
--- /dev/null
@@ -0,0 +1,114 @@
+// Created on: 1991-07-24
+// Created by: Michel CHAUVAT
+// Copyright (c) 1991-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Extrema_FunctPSNorm_HeaderFile
+#define _Extrema_FunctPSNorm_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_DefineAlloc.hxx>
+
+#include <gp_Pnt.hxx>
+#include <Adaptor3d_SurfacePtr.hxx>
+#include <Standard_Real.hxx>
+#include <TColStd_SequenceOfReal.hxx>
+#include <Extrema_SequenceOfPOnSurf.hxx>
+#include <Standard_Boolean.hxx>
+#include <math_FunctionSetWithDerivatives.hxx>
+#include <Standard_Integer.hxx>
+#include <math_Vector.hxx>
+class Standard_OutOfRange;
+class gp_Pnt;
+class Adaptor3d_Surface;
+class math_Matrix;
+class Extrema_POnSurf;
+
+
+
+//! 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.
+class Extrema_FuncPSNorm  : public math_FunctionSetWithDerivatives
+{
+public:
+
+  DEFINE_STANDARD_ALLOC
+
+  
+  Standard_EXPORT Extrema_FuncPSNorm();
+  
+  Standard_EXPORT Extrema_FuncPSNorm(const gp_Pnt& P, const Adaptor3d_Surface& S);
+  
+  //! sets the field mysurf of the function.
+  Standard_EXPORT void Initialize (const Adaptor3d_Surface& S);
+  
+  //! sets the field mysurf of the function.
+  Standard_EXPORT void SetPoint (const gp_Pnt& P);
+  
+  Standard_EXPORT Standard_Integer NbVariables() const Standard_OVERRIDE;
+  
+  Standard_EXPORT Standard_Integer NbEquations() const Standard_OVERRIDE;
+  
+  //! Calculate Fi(U,V).
+  Standard_EXPORT Standard_Boolean Value (const math_Vector& UV, math_Vector& F) Standard_OVERRIDE;
+  
+  //! Calculate Fi'(U,V).
+  Standard_EXPORT Standard_Boolean Derivatives (const math_Vector& UV, math_Matrix& DF) Standard_OVERRIDE;
+  
+  //! Calculate Fi(U,V) and Fi'(U,V).
+  Standard_EXPORT Standard_Boolean Values (const math_Vector& UV, math_Vector& F, math_Matrix& DF) Standard_OVERRIDE;
+  
+  //! Save the found extremum.
+  Standard_EXPORT virtual Standard_Integer GetStateNumber() Standard_OVERRIDE;
+  
+  //! Return the number of found extrema.
+  Standard_EXPORT Standard_Integer NbExt() const;
+  
+  //! Return the value of the Nth distance.
+  Standard_EXPORT Standard_Real SquareDistance (const Standard_Integer N) const;
+  
+  //! Returns the Nth extremum.
+  Standard_EXPORT const Extrema_POnSurf& Point (const Standard_Integer N) const;
+
+private:
+
+  gp_Pnt myP;
+  Adaptor3d_SurfacePtr myS;
+  Standard_Real myU;
+  Standard_Real myV;
+  gp_Pnt myPs;
+  TColStd_SequenceOfReal mySqDist;
+  Extrema_SequenceOfPOnSurf myPoint;
+  Standard_Boolean myPinit;
+  Standard_Boolean mySinit;
+};
+#endif // _Extrema_FunctPSNorm_HeaderFile
index 31e0b78..3ad87ef 100644 (file)
@@ -27,7 +27,7 @@
 #include <Extrema_HArray2OfPOnSurfParams.hxx>
 #include <Extrema_HUBTreeOfSphere.hxx>
 #include <Bnd_HArray1OfSphere.hxx>
-#include <Extrema_FuncExtPS.hxx>
+#include <Extrema_FuncPSNorm.hxx>
 #include <Adaptor3d_SurfacePtr.hxx>
 #include <Extrema_ExtFlag.hxx>
 #include <Extrema_ExtAlgo.hxx>
@@ -148,7 +148,7 @@ private:
   Handle(Extrema_HArray2OfPOnSurfParams) myPoints;
   Extrema_HUBTreeOfSphere mySphereUBTree;
   Handle(Bnd_HArray1OfSphere) mySphereArray;
-  Extrema_FuncExtPS myF;
+  Extrema_FuncPSNorm myF;
   Adaptor3d_SurfacePtr myS;
   Extrema_ExtFlag myFlag;
   Extrema_ExtAlgo myAlgo;
index 17b1468..b48ef0b 100644 (file)
 // commercial license or contractual agreement.
 
 
-#include <Adaptor3d_Surface.hxx>
-#include <Extrema_FuncExtPS.hxx>
 #include <Extrema_GenLocateExtPS.hxx>
+
+#include <Adaptor3d_Surface.hxx>
+#include <Extrema_FuncPSNorm.hxx>
+#include <Extrema_FuncPSDist.hxx>
 #include <Extrema_POnSurf.hxx>
-#include <gp.hxx>
 #include <gp_Pnt.hxx>
 #include <math_FunctionSetRoot.hxx>
-#include <math_NewtonFunctionSetRoot.hxx>
+#include <math_BFGS.hxx>
 #include <math_Vector.hxx>
-#include <Standard_DomainError.hxx>
 #include <StdFail_NotDone.hxx>
 
-//=============================================================================
-Extrema_GenLocateExtPS::Extrema_GenLocateExtPS () { myDone = Standard_False; }
-//=============================================================================
-
-Extrema_GenLocateExtPS::Extrema_GenLocateExtPS (const gp_Pnt&          P,
-                                               const Adaptor3d_Surface& S, 
-                                               const Standard_Real    U0, 
-                                               const Standard_Real    V0,
-                                               const Standard_Real    TolU, 
-                                               const Standard_Real    TolV)
-/*-----------------------------------------------------------------------------
-Function:
-  Find (U,V) close to (U0,V0) so that dist(S(U,V),P) was extreme.
-
-Method:
-  If (u,v) is a solution, it is possible to write:
-   { F1(u,v) = (S(u,v)-P).dS/du(u,v) = 0.
-   { F2(u,v) = (S(u,v)-P).dS/dv(u,v) = 0.
-  The problem consists in finding, in the interval of surface definition,
-  the root of the system closest to (U0,V0).
-  Use class math_FunctionSetRoot with the following construction arguments:
-  - F: Extrema_FuncExtPS created from P and S,
-  - U0V0: math_Vector (U0,V0),
-  - Tol: Min(TolU,TolV),            
-                                   
-  - math_Vector (Uinf,Usup),
-  - math_Vector (Vinf,Vsup),
-  - 100. .
----------------------------------------------------------------------------*/  
+//=======================================================================
+//function : Extrema_GenLocateExtPS
+//purpose  : 
+//=======================================================================
+Extrema_GenLocateExtPS::Extrema_GenLocateExtPS(const Adaptor3d_Surface& theS,
+                                               const Standard_Real theTolU,
+                                               const Standard_Real theTolV)
+: mySurf(theS),
+  myTolU(theTolU), myTolV(theTolV),
+  myDone(Standard_False),
+  mySqDist(-1.0)
+{
+}
+
+//=======================================================================
+//function : Perform
+//purpose  : 
+//=======================================================================
+void Extrema_GenLocateExtPS::Perform(const gp_Pnt& theP,
+                                     const Standard_Real theU0,
+                                     const Standard_Real theV0,
+                                     const Standard_Boolean isDistanceCriteria)
 {
   myDone = Standard_False;
 
-  Standard_Real Uinf, Usup, Vinf, Vsup;
-  Uinf = S.FirstUParameter();
-  Usup = S.LastUParameter();
-  Vinf = S.FirstVParameter();
-  Vsup = S.LastVParameter();
+  // Prepare initial data structures.
+  math_Vector aTol(1, 2), aStart(1, 2), aBoundInf(1, 2), aBoundSup(1, 2);
+
+  // Tolerance.
+  aTol(1) = myTolU;
+  aTol(2) = myTolV;
+
+  // Initial solution approximation.
+  aStart(1) = theU0;
+  aStart(2) = theV0;
 
-  Extrema_FuncExtPS F (P,S);
-  math_Vector Tol(1, 2), Start(1, 2), BInf(1, 2), BSup(1, 2);
+  // Borders.
+  aBoundInf(1) = mySurf.FirstUParameter();
+  aBoundInf(2) = mySurf.FirstVParameter();
+  aBoundSup(1) = mySurf.LastUParameter();
+  aBoundSup(2) = mySurf.LastVParameter();
 
-  Tol(1) = TolU;
-  Tol(2) = TolV;
+  if (isDistanceCriteria == Standard_False)
+  {
+    // Normal projection criteria.
+    Extrema_FuncPSNorm F(theP,mySurf);
 
-  Start(1) = U0;
-  Start(2) = V0;
+    math_FunctionSetRoot SR (F, aTol);
+    SR.Perform(F, aStart, aBoundInf, aBoundSup);
+    if (!SR.IsDone()) 
+      return;
 
-  BInf(1) = Uinf;
-  BInf(2) = Vinf;
-  BSup(1) = Usup;
-  BSup(2) = Vsup;
+    mySqDist = F.SquareDistance(1);
+    myPoint = F.Point(1);
+    myDone = Standard_True;
+  }
+  else
+  {
+    // Distance criteria.
+    Extrema_FuncPSDist F(mySurf, theP);
+    math_BFGS aSolver(2);
+    aSolver.Perform(F, aStart);
 
-  math_FunctionSetRoot SR (F, Tol);
-  SR.Perform(F, Start, BInf, BSup);
-  if (!SR.IsDone()) 
-    return;
+    if (!aSolver.IsDone()) 
+      return;
 
-  mySqDist = F.SquareDistance(1);
-  myPoint = F.Point(1);
-  myDone = Standard_True;
+    math_Vector aResPnt(1,2);
+    aSolver.Location(aResPnt);
+    mySqDist = aSolver.Minimum();
+    myPoint.SetParameters(aResPnt(1), aResPnt(2), mySurf.Value(aResPnt(1), aResPnt(2)));
+    myDone = Standard_True;
+  }
 }
-//=============================================================================
 
-Standard_Boolean Extrema_GenLocateExtPS::IsDone () const { return myDone; }
-//=============================================================================
+//=======================================================================
+//function : IsDone
+//purpose  : 
+//=======================================================================
+Standard_Boolean Extrema_GenLocateExtPS::IsDone () const
+{
+  return myDone;
+}
 
+//=======================================================================
+//function : SquareDistance
+//purpose  : 
+//=======================================================================
 Standard_Real Extrema_GenLocateExtPS::SquareDistance () const
 {
   if (!IsDone()) { StdFail_NotDone::Raise(); }
   return mySqDist;
 }
-//=============================================================================
 
+//=======================================================================
+//function : Point
+//purpose  : 
+//=======================================================================
 const Extrema_POnSurf& Extrema_GenLocateExtPS::Point () const
 {
   if (!IsDone()) { StdFail_NotDone::Raise(); }
   return myPoint;
 }
-//=============================================================================
index 3245d69..07f0e5d 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <Standard.hxx>
 #include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
 
 #include <Standard_Boolean.hxx>
 #include <Standard_Real.hxx>
@@ -33,23 +32,27 @@ class Extrema_POnSurf;
 
 //! With a close point, it calculates the distance
 //! between a point and a surface.
-//! This distance can be a minimum or a maximum.
+//! Criteria type is defined in "Perform" method.
 class Extrema_GenLocateExtPS 
 {
 public:
 
   DEFINE_STANDARD_ALLOC
 
+  //! Constructor.
+  Standard_EXPORT Extrema_GenLocateExtPS(const Adaptor3d_Surface& theS,
+                                         const Standard_Real theTolU = Precision::PConfusion(),
+                                         const Standard_Real theTolV = Precision::PConfusion());
   
-  Standard_EXPORT Extrema_GenLocateExtPS();
-  
-  //! Calculates the distance with a close point.
-  //! The close point is defined by the parameter values
-  //! U0 and V0.
-  //! The function F(u,v)=distance(S(u,v),p) has an
-  //! extremun when gradient(F)=0. The algorithm searchs
-  //! a zero near the close point.
-  Standard_EXPORT Extrema_GenLocateExtPS(const gp_Pnt& P, const Adaptor3d_Surface& S, const Standard_Real U0, const Standard_Real V0, const Standard_Real TolU, const Standard_Real TolV);
+  //! Calculates the extrema between the point and the surface using a close point.
+  //! The close point is defined by the parameter values theU0 and theV0.
+  //! Type of the algorithm depends on the isDistanceCriteria flag.
+  //! If flag value is false - normal projection criteria will be used.
+  //! If flag value is true - distance criteria will be used.
+  Standard_EXPORT void Perform(const gp_Pnt& theP,
+                               const Standard_Real theU0,
+                               const Standard_Real theV0,
+                               const Standard_Boolean isDistanceCriteria = Standard_False);
   
   //! Returns True if the distance is found.
   Standard_EXPORT Standard_Boolean IsDone() const;
@@ -60,20 +63,19 @@ public:
   //! Returns the point of the extremum distance.
   Standard_EXPORT const Extrema_POnSurf& Point() const;
 
-
-
-
-protected:
-
-
-
-
-
 private:
 
+  const Extrema_GenLocateExtPS& operator=(const Extrema_GenLocateExtPS&);
+  Extrema_GenLocateExtPS(const Extrema_GenLocateExtPS&);
 
+  // Input.
+  const Adaptor3d_Surface& mySurf;
+  Standard_Real myTolU, myTolV;
 
+  // State.
   Standard_Boolean myDone;
+
+  // Result.
   Standard_Real mySqDist;
   Extrema_POnSurf myPoint;
 
index 33f2e0b..3be6cd0 100644 (file)
@@ -72,8 +72,10 @@ Extrema_FuncExtCC.lxx
 Extrema_FuncExtCS.cxx
 Extrema_FuncExtCS.hxx
 Extrema_FuncExtPC.gxx
-Extrema_FuncExtPS.cxx
-Extrema_FuncExtPS.hxx
+Extrema_FuncPSNorm.cxx
+Extrema_FuncPSNorm.hxx
+Extrema_FuncPSDist.cxx
+Extrema_FuncPSDist.hxx
 Extrema_FuncExtSS.cxx
 Extrema_FuncExtSS.hxx
 Extrema_GenExtCC.gxx
index 187ecc2..3a9982d 100644 (file)
@@ -2782,9 +2782,8 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
 
           theQSurf->D0(aUquad, aVquad, aPQuad);
 
-          Extrema_GenLocateExtPS anExtr(aPQuad, thePSurf->Surface(), aU0, aV0,
-                                        Precision::PConfusion(),
-                                        Precision::PConfusion());
+          Extrema_GenLocateExtPS anExtr(thePSurf->Surface());
+          anExtr.Perform(aPQuad, aU0, aV0);
 
           if(!anExtr.IsDone())
           {
@@ -2946,9 +2945,8 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
           
           theQSurf->D0(aUquad, aVquad, aPQuad);
 
-          Extrema_GenLocateExtPS anExtr(aPQuad, thePSurf->Surface(), aU0, aV0,
-                                        Precision::PConfusion(),
-                                        Precision::PConfusion());
+          Extrema_GenLocateExtPS anExtr(thePSurf->Surface());
+          anExtr.Perform(aPQuad, aU0, aV0);
 
           if(!anExtr.IsDone())
           {
index bc879f5..395b715 100644 (file)
@@ -1312,8 +1312,9 @@ void IntTools_BeanFaceIntersector::ComputeRangeFromStartPoint(const Standard_Boo
 
     // 
     gp_Pnt aPoint = myCurve.Value(aCurPar);
-    Extrema_GenLocateExtPS anExtrema(aPoint, mySurface, U, V, 1.e-10, 1.e-10);
-    
+    Extrema_GenLocateExtPS anExtrema(mySurface, 1.e-10, 1.e-10);
+    anExtrema.Perform(aPoint, U, V);
+
     if(anExtrema.IsDone()) {
       if(anExtrema.SquareDistance() < myCriteria * myCriteria) {
         Extrema_POnSurf aPOnSurf = anExtrema.Point();
index aa0c492..bf57d64 100644 (file)
@@ -617,8 +617,9 @@ static Standard_Real SQDistPointSurface(const gp_Pnt &thePnt,
                                         const Standard_Real theU0,
                                         const Standard_Real theV0)
 {
-  const Extrema_GenLocateExtPS aExtPS(thePnt, theSurf, theU0, theV0,
-                      Precision::PConfusion(), Precision::PConfusion());
+  Extrema_GenLocateExtPS aExtPS(theSurf);
+  aExtPS.Perform(thePnt, theU0, theV0);
+
   if(!aExtPS.IsDone())
     return RealLast();
   
index 57cc349..4b410a5 100644 (file)
@@ -367,7 +367,8 @@ static gp_Pnt2d Function_Value(const Standard_Real theU,
   }
 
   // Try to run simple search with initial point (U0, V0).
-  Extrema_GenLocateExtPS  locext(p, SurfLittle, U0, V0, theData.myTolU, theData.myTolV);
+  Extrema_GenLocateExtPS  locext(SurfLittle, theData.myTolU, theData.myTolV);
+  locext.Perform(p, U0, V0);
   if (locext.IsDone()) 
   {
     locext.Point().Parameter(u, v);
@@ -1218,9 +1219,9 @@ Handle(Adaptor2d_HCurve2d)
          myProjIsDone = Standard_False;
          Dist2Min = RealLast();
          Curve->D0(Param.Value(i), pntproj);
-         Extrema_GenLocateExtPS  aLocateExtPS
-           (pntproj, Surf->Surface(), U0, V0, TolU, TolV) ;
-         
+          Extrema_GenLocateExtPS  aLocateExtPS(Surf->Surface(), TolU, TolV);
+          aLocateExtPS.Perform(pntproj, U0, V0);
+
          if (aLocateExtPS.IsDone())
           {
            if (aLocateExtPS.SquareDistance() < DistTol3d * DistTol3d)
@@ -1315,9 +1316,10 @@ Handle(Adaptor2d_HCurve2d)
              Uaux = 2*aUinf - U0 + uperiod;
            else 
              Uaux = 2*aUsup - U0 - uperiod;
-           Extrema_GenLocateExtPS  locext(pntproj, 
-                                          Surf->Surface(), 
-                                          Uaux, V0, TolU, TolV);
+
+            Extrema_GenLocateExtPS  locext(Surf->Surface(), TolU, TolV);
+            locext.Perform(pntproj, Uaux, V0);
+
            if (locext.IsDone())
              if (locext.SquareDistance() < DistTol3d * DistTol3d) {  //OCC217
              //if (locext.SquareDistance() < Tol3d * Tol3d) {
@@ -1341,9 +1343,10 @@ Handle(Adaptor2d_HCurve2d)
              Vaux = 2*aVinf - V0 + vperiod;
            else 
              Vaux = 2*aVsup - V0 - vperiod;
-           Extrema_GenLocateExtPS  locext(pntproj, 
-                                          Surf->Surface(), 
-                                          U0, Vaux, TolU, TolV) ;
+
+            Extrema_GenLocateExtPS  locext(Surf->Surface(), TolU, TolV);
+            locext.Perform(pntproj, U0, Vaux);
+
            if (locext.IsDone())
              if (locext.SquareDistance() < DistTol3d * DistTol3d) {  //OCC217
              //if (locext.SquareDistance() < Tol3d * Tol3d) {
@@ -1369,9 +1372,10 @@ Handle(Adaptor2d_HCurve2d)
              Vaux = 2*Vinf - V0 + vperiod;
            else 
              Vaux = 2*Vsup - V0 - vperiod;
-           Extrema_GenLocateExtPS  locext(pntproj, 
-                                          Surf->Surface(), 
-                                          Uaux, Vaux, TolU, TolV);
+
+            Extrema_GenLocateExtPS  locext(Surf->Surface(), TolU, TolV);
+            locext.Perform(pntproj, Uaux, Vaux);
+
            if (locext.IsDone())
              if (locext.SquareDistance() < DistTol3d * DistTol3d) {
              //if (locext.SquareDistance() < Tol3d * Tol3d) {
@@ -1584,8 +1588,10 @@ Handle(Geom2d_BSplineCurve)
          for(i = 1;i <= Curve->NbPoles();i++) {
            myProjIsDone = Standard_False;
            Dist2Min = IntegerLast();
-           Extrema_GenLocateExtPS  extrloc(BSC->Pole(i),Surf->Surface(),(p11.X()+p22.X())/2,
-                                           (p11.Y()+p22.Y())/2,TolU,TolV) ;
+
+            Extrema_GenLocateExtPS  extrloc(Surf->Surface(), TolU, TolV);
+            extrloc.Perform(BSC->Pole(i), (p11.X()+p22.X())/2, (p11.Y()+p22.Y())/2);
+
            if (extrloc.IsDone()) {
              Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
              if (Dist2Min < DistTol3d * DistTol3d) {  //OCC217
@@ -1622,8 +1628,10 @@ Handle(Geom2d_BSplineCurve)
          TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
          for(i = 1;i <= Curve->NbPoles();i++) {
            Dist2Min = IntegerLast();
-           Extrema_GenLocateExtPS  extrloc(BC->Pole(i),Surf->Surface(),0.5,
-                                           0.5,TolU,TolV) ;
+
+            Extrema_GenLocateExtPS  extrloc(Surf->Surface(), TolU, TolV);
+            extrloc.Perform(BC->Pole(i), 0.5, 0.5);
+
            if (extrloc.IsDone()) {
              Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
              if (Dist2Min < DistTol3d * DistTol3d) {  //OCC217
@@ -1685,8 +1693,10 @@ Handle(Geom2d_BSplineCurve)
          for(i = 1;i <= Curve->NbPoles();i++) {
            myProjIsDone = Standard_False;
            Dist2Min = IntegerLast();
-           Extrema_GenLocateExtPS  extrloc(BSC->Pole(i),Surf->Surface(),(p11.X()+p22.X())/2,
-                                           (p11.Y()+p22.Y())/2,TolU,TolV) ;
+
+            Extrema_GenLocateExtPS  extrloc(Surf->Surface(), TolU, TolV);
+            extrloc.Perform(BSC->Pole(i), (p11.X()+p22.X())/2, (p11.Y()+p22.Y())/2);
+
            if (extrloc.IsDone()) {
              Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
              if (Dist2Min < DistTol3d * DistTol3d) {  //OCC217
@@ -1723,8 +1733,10 @@ Handle(Geom2d_BSplineCurve)
          TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
          for(i = 1;i <= Curve->NbPoles();i++) {
            Dist2Min = IntegerLast();
-           Extrema_GenLocateExtPS  extrloc(BC->Pole(i),Surf->Surface(),0.5,
-                                           0.5,TolU,TolV) ;
+
+            Extrema_GenLocateExtPS  extrloc(Surf->Surface(), TolU, TolV);
+            extrloc.Perform(BC->Pole(i), 0.5, 0.5);
+
            if (extrloc.IsDone()) {
              Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
              if (Dist2Min < DistTol3d * DistTol3d) {  //OCC217
index 7bc686d..a988e5c 100644 (file)
@@ -1364,7 +1364,7 @@ static Standard_Integer OCC24945 (Draw_Interpretor& di, Standard_Integer argc, c
   return 0;
 }
 
-#include <Extrema_FuncExtPS.hxx>
+#include <Extrema_FuncPSNorm.hxx>
 #include <math_FunctionSetRoot.hxx>
 #include <math_Vector.hxx>
 #include <BRepBuilderAPI_MakeVertex.hxx>
@@ -1401,7 +1401,7 @@ static Standard_Integer OCC24137 (Draw_Interpretor& theDI, Standard_Integer theN
 
   gp_Pnt aPnt = BRep_Tool::Pnt (aVert), aRes;
 
-  Extrema_FuncExtPS    anExtFunc;
+  Extrema_FuncPSNorm    anExtFunc;
   math_FunctionSetRoot aRoot (anExtFunc, aNbIts);
 
   math_Vector aTolUV (1, 2), aUVinf  (1, 2), aUVsup  (1, 2), aFromUV (1, 2);
index d4e4812..15e7957 100644 (file)
@@ -16,6 +16,7 @@
 #include <QABugs.hxx>
 
 #include <gp_Ax2.hxx>
+#include <Extrema_GenLocateExtPS.hxx>
 #include <Geom_Circle.hxx>
 #include <Geom_SurfaceOfLinearExtrusion.hxx>
 #include <NCollection_List.hxx>
@@ -36,6 +37,7 @@
 #include <TopoDS_Edge.hxx>
 #include <BRep_Builder.hxx>
 #include <BRepTools.hxx>
+#include <BRepAdaptor_Surface.hxx>
 #include <TopoDS.hxx>
 #include <DBRep.hxx>
 
@@ -1571,6 +1573,55 @@ static Standard_Integer OCC26930(Draw_Interpretor& theDI,
   return 0;
 }
 
+//=======================================================================
+//function : OCC27466
+//purpose :
+//=======================================================================
+static Standard_Integer OCC27466(Draw_Interpretor& theDI,
+  Standard_Integer  theNArg,
+  const char ** theArgVal)
+{
+  if (theNArg != 4)
+  {
+    cout << "Use: " << theArgVal[0] << " face point start_pnt2d" << endl;
+    return 1;
+  }
+
+  TopoDS_Face aFace = TopoDS::Face(DBRep::Get(theArgVal[1], TopAbs_FACE, Standard_True));
+  if (aFace.IsNull())
+    return 1;
+  gp_Pnt aPnt;
+  if (!DrawTrSurf::GetPoint(theArgVal[2], aPnt))
+    return 1;
+  gp_Pnt2d aUV;
+  if (!DrawTrSurf::GetPoint2d(theArgVal[3], aUV))
+    return 1;
+  BRepAdaptor_Surface aSurf(aFace);
+
+  Standard_Real aTolU = Precision::PConfusion();
+  Standard_Real aTolV = Precision::PConfusion();
+
+  Extrema_GenLocateExtPS anExtrema(aSurf, aTolU, aTolV);
+  anExtrema.Perform(aPnt, aUV.X(), aUV.Y(), Standard_True);
+
+  if (!anExtrema.IsDone())
+  {
+    theDI << "Error: Extrema is not done";
+  }
+  else
+  {
+    Standard_Real aSqDist = anExtrema.SquareDistance();
+    gp_Pnt aResPnt = anExtrema.Point().Value();
+    Standard_Real u, v;
+    anExtrema.Point().Parameter(u, v);
+    gp_Pnt2d aResUV(u, v);
+    DrawTrSurf::Set((TCollection_AsciiString(theArgVal[2]) + "_res").ToCString(), aResPnt);
+    DrawTrSurf::Set((TCollection_AsciiString(theArgVal[3]) + "_res").ToCString(), aResUV);
+    theDI << theArgVal[2] << "_res and " << theArgVal[3] << "_res are created, dist=" << sqrt(aSqDist);
+  }
+  return 0;
+}
+
 void QABugs::Commands_20(Draw_Interpretor& theCommands) {
   const char *group = "QABugs";
 
@@ -1579,6 +1630,7 @@ void QABugs::Commands_20(Draw_Interpretor& theCommands) {
   theCommands.Add("OCC27021", "OCC27021", __FILE__, OCC27021, group);
   theCommands.Add("OCC27235", "OCC27235", __FILE__, OCC27235, group);
   theCommands.Add("OCC26930", "OCC26930", __FILE__, OCC26930, group);
+  theCommands.Add("OCC27466", "OCC27466", __FILE__, OCC27466, group);
 
   return;
 }
diff --git a/tests/bugs/moddata_3/bug27466 b/tests/bugs/moddata_3/bug27466
new file mode 100644 (file)
index 0000000..3a78417
--- /dev/null
@@ -0,0 +1,25 @@
+puts "================"
+puts "OCC27466: "
+puts "================"
+puts ""
+####################
+## The algorithm Extrema_GenLocateExtPS gives incorrect result
+####################
+
+pload QAcommands
+
+restore [locate_data_file bug27466.brep] a
+
+point pnt -5.909487750466874e-006 -0.1557578329355927 0.1298542821722014
+point uv0 0.748729882974883 0.5000000063028793
+
+set out [OCC27466 a pnt uv0]
+if [regexp {dist=([0-9.+-e]*)} $out dummy dist] {
+  if {$dist > 1e-7} {
+    puts "Error: distance of projection is too large ($dist)"
+  } else {
+    puts "Test passed"
+  }
+} else {
+  puts "Error: projection failure"
+}