From 6220ba10a3d6085a7fd6c6f002de5300403d18a3 Mon Sep 17 00:00:00 2001 From: aml Date: Fri, 19 Feb 2016 14:55:13 +0300 Subject: [PATCH] 0027184: BRepExtrema_DistShapeShape returns wrong result. Local optimization default algorithm is changed to "distance" based. Test case added. --- src/Extrema/Extrema_GenExtSS.cxx | 104 ++++++++++++++++++++++++++++++- tests/bugs/fclasses/bug27184 | 19 ++++++ 2 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 tests/bugs/fclasses/bug27184 diff --git a/src/Extrema/Extrema_GenExtSS.cxx b/src/Extrema/Extrema_GenExtSS.cxx index 03bc58eadd..4d7ffd5840 100644 --- a/src/Extrema/Extrema_GenExtSS.cxx +++ b/src/Extrema/Extrema_GenExtSS.cxx @@ -18,12 +18,84 @@ #include #include #include +#include #include +#include #include #include #include #include +//! This class represents distance objective function for surface / surface. +class Extrema_FuncDistSS : public math_MultipleVarFunctionWithGradient +{ +public: + DEFINE_STANDARD_ALLOC + + Standard_EXPORT Extrema_FuncDistSS(const Adaptor3d_Surface& S1, + const Adaptor3d_Surface& S2) + : myS1(&S1), + myS2(&S2) + { + } + + Standard_EXPORT Standard_Integer NbVariables() const + { + return 4; + } + + Standard_EXPORT virtual Standard_Boolean Value(const math_Vector& X,Standard_Real& F) + { + F = myS1->Value(X(1), X(2)).SquareDistance(myS2->Value(X(3), X(4))); + return true; + } + + Standard_EXPORT Standard_Boolean Gradient(const math_Vector& X,math_Vector& G) + { + gp_Pnt P1, P2; + gp_Vec Du1s1, Dv1s1; + gp_Vec Du2s2, Dv2s2; + myS1->D1(X(1),X(2),P1,Du1s1,Dv1s1); + myS2->D1(X(3),X(4),P2,Du2s2,Dv2s2); + + gp_Vec P1P2 (P2,P1); + + G(1) = P1P2.Dot(Du1s1); + G(2) = P1P2.Dot(Dv1s1); + G(3) = -P1P2.Dot(Du2s2); + G(4) = -P1P2.Dot(Dv2s2); + + return true; + } + + Standard_EXPORT virtual Standard_Boolean Values(const math_Vector& X,Standard_Real& F,math_Vector& G) + { + F = myS1->Value(X(1), X(2)).SquareDistance(myS2->Value(X(3), X(4))); + + gp_Pnt P1, P2; + gp_Vec Du1s1, Dv1s1; + gp_Vec Du2s2, Dv2s2; + myS1->D1(X(1),X(2),P1,Du1s1,Dv1s1); + myS2->D1(X(3),X(4),P2,Du2s2,Dv2s2); + + gp_Vec P1P2 (P2,P1); + + G(1) = P1P2.Dot(Du1s1); + G(2) = P1P2.Dot(Dv1s1); + G(3) = -P1P2.Dot(Du2s2); + G(4) = -P1P2.Dot(Dv2s2); + + return true; + } + +protected: + +private: + + const Adaptor3d_Surface *myS1; + const Adaptor3d_Surface *myS2; +}; + //======================================================================= //function : Extrema_GenExtSS //purpose : @@ -271,14 +343,42 @@ b- Calcul des minima: UV(3) = U20 + (N2Umin - 1) * PasU2; UV(4) = V20 + (N2Vmin - 1) * PasV2; - math_FunctionSetRoot SR1(myF, Tol); - SR1.Perform(myF, UV, UVinf, UVsup); + Extrema_FuncDistSS aGFSS(S1, *myS2); + math_BFGS aBFGSSolver(4); + aBFGSSolver.Perform(aGFSS, UV); + if (aBFGSSolver.IsDone()) + { + aBFGSSolver.Location(UV); + + // Store result in myF. + myF.Value(UV , UV); + myF.GetStateNumber(); + } + else + { + // If optimum is not computed successfully then compute by old approach. + + // Restore initial point. + UV(1) = U10 + (N1Umin - 1) * PasU1; + UV(2) = V10 + (N1Vmin - 1) * PasV1; + UV(3) = U20 + (N2Umin - 1) * PasU2; + UV(4) = V20 + (N2Vmin - 1) * PasV2; + + math_FunctionSetRoot SR1(myF, Tol); + SR1.Perform(myF, UV, UVinf, UVsup); + } + + //math_FunctionSetRoot SR1(myF, Tol); + //SR1.Perform(myF, UV, UVinf, UVsup); UV(1) = U10 + (N1Umax - 1) * PasU1; UV(2) = V10 + (N1Vmax - 1) * PasV1; UV(3) = U20 + (N2Umax - 1) * PasU2; UV(4) = V20 + (N2Vmax - 1) * PasV2; + // It is impossible to compute max distance in the same manner, + // since for the distance functional for max have bad definition. + // So, for max computation old approach is used. math_FunctionSetRoot SR2(myF, Tol); SR2.Perform(myF, UV, UVinf, UVsup); diff --git a/tests/bugs/fclasses/bug27184 b/tests/bugs/fclasses/bug27184 new file mode 100644 index 0000000000..f76bd7623b --- /dev/null +++ b/tests/bugs/fclasses/bug27184 @@ -0,0 +1,19 @@ +puts "========" +puts "OCC27184" +puts "========" +puts "" +############################################## +# BRepExtrema_DistShapeShape returns wrong result +# Correct distance is 0.0 +############################################## + +restore [locate_data_file bug27184.brep] aShape +explode aShape +set anInfo [distmini d aShape_1 aShape_2] + +# Check extrema distance +set absTol 1.0e-10 +set relTol 0.001 +set aDist_Exp 0.0 +set aDist [dval d_val] +checkreal "Distance value check" $aDist $aDist_Exp $absTol $relTol \ No newline at end of file