0027184: BRepExtrema_DistShapeShape returns wrong result.
authoraml <aml@opencascade.com>
Fri, 19 Feb 2016 11:55:13 +0000 (14:55 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 8 Apr 2016 08:42:21 +0000 (11:42 +0300)
Local optimization default algorithm is changed to "distance" based.
Test case added.

src/Extrema/Extrema_GenExtSS.cxx
tests/bugs/fclasses/bug27184 [new file with mode: 0644]

index 03bc58e..4d7ffd5 100644 (file)
 #include <Adaptor3d_Surface.hxx>
 #include <Extrema_GenExtSS.hxx>
 #include <Extrema_POnSurf.hxx>
+#include <math_BFGS.hxx>
 #include <math_FunctionSetRoot.hxx>
+#include <math_MultipleVarFunctionWithGradient.hxx>
 #include <math_Vector.hxx>
 #include <Standard_OutOfRange.hxx>
 #include <Standard_TypeMismatch.hxx>
 #include <StdFail_NotDone.hxx>
 
+//! 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 (file)
index 0000000..f76bd76
--- /dev/null
@@ -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