]> OCCT Git - occt.git/commitdiff
0030679: Attached model hangs most of OCCT common functionality IR-2019-05-17
authormsv <msv@opencascade.com>
Mon, 13 May 2019 13:19:35 +0000 (16:19 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 16 May 2019 16:46:25 +0000 (19:46 +0300)
Evaluator of offset surface has been protected against evaluation at infinite parameters. Now it throws exception when evaluating such data.

The methods IsUClosed and IsVClosed of the class ShapeAnalysis_Surface have been corrected to avoid evaluation of the surface at infinite parameters (fighting with regressions "parasolid doc_3 E3" and "parasolid doc_2 A3" in products).

src/GeomEvaluator/GeomEvaluator_OffsetSurface.cxx
src/ShapeAnalysis/ShapeAnalysis_Surface.cxx
tests/bugs/modalg_7/bug30679 [new file with mode: 0644]

index d2fcead403c6ef7896bbf9c856754aeb9e6f469c..b115be3f47bbcda182affc2ddf749f523f699136 100644 (file)
@@ -23,6 +23,7 @@
 #include <GeomAdaptor_HSurface.hxx>
 #include <gp_Vec.hxx>
 #include <Standard_RangeError.hxx>
+#include <Standard_NumericError.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(GeomEvaluator_OffsetSurface,GeomEvaluator_Surface)
 
@@ -212,6 +213,21 @@ static void derivatives(Standard_Integer theMaxOrder,
   }
 }
 
+inline Standard_Boolean IsInfiniteCoord (const gp_Vec& theVec)
+{
+  return Precision::IsInfinite (theVec.X()) ||
+         Precision::IsInfinite (theVec.Y()) ||
+         Precision::IsInfinite (theVec.Z());
+}
+
+inline void CheckInfinite (const gp_Vec& theVecU, const gp_Vec& theVecV)
+{
+  if (IsInfiniteCoord (theVecU) || IsInfiniteCoord (theVecV))
+  {
+    throw Standard_NumericError ("GeomEvaluator_OffsetSurface: Evaluation of infinite parameters");
+  }
+}
+
 } // end of anonymous namespace
 
 GeomEvaluator_OffsetSurface::GeomEvaluator_OffsetSurface(
@@ -251,6 +267,9 @@ void GeomEvaluator_OffsetSurface::D0(
   {
     gp_Vec aD1U, aD1V;
     BaseD1 (aU, aV, theValue, aD1U, aD1V);
+
+    CheckInfinite (aD1U, aD1V);
+
     try 
     {
       CalculateD0(aU, aV, theValue, aD1U, aD1V);
@@ -276,6 +295,9 @@ void GeomEvaluator_OffsetSurface::D1(
   {
     gp_Vec aD2U, aD2V, aD2UV;
     BaseD2 (aU, aV, theValue, theD1U, theD1V, aD2U, aD2V, aD2UV);
+
+    CheckInfinite (theD1U, theD1V);
+
     try 
     {
       CalculateD1(aU, aV, theValue, theD1U, theD1V, aD2U, aD2V, aD2UV);
@@ -303,6 +325,9 @@ void GeomEvaluator_OffsetSurface::D2(
     gp_Vec aD3U, aD3V, aD3UUV, aD3UVV;
     BaseD3 (aU, aV, theValue, theD1U, theD1V,
             theD2U, theD2V, theD2UV, aD3U, aD3V, aD3UUV, aD3UVV);
+
+    CheckInfinite (theD1U, theD1V);
+
     try
     {
       CalculateD2 (aU, aV, theValue, theD1U, theD1V,
@@ -331,6 +356,9 @@ void GeomEvaluator_OffsetSurface::D3(
   {
     BaseD3 (aU, aV, theValue, theD1U, theD1V,
             theD2U, theD2V, theD2UV, theD3U, theD3V, theD3UUV, theD3UVV);
+
+    CheckInfinite (theD1U, theD1V);
+
     try
     {
       CalculateD3 (aU, aV, theValue, theD1U, theD1V,
@@ -363,6 +391,9 @@ gp_Vec GeomEvaluator_OffsetSurface::DN(
     gp_Pnt aP;
     gp_Vec aD1U, aD1V;
     BaseD1 (aU, aV, aP, aD1U, aD1V);
+
+    CheckInfinite (aD1U, aD1V);
+
     try
     {
       return CalculateDN (aU, aV, theDerU, theDerV, aD1U, aD1V);
index 2efd9c0c3376b772715ea30d92c2bc0fd2f2fd01..93c2d0f89201d6e721b5927b0ac8613430134b3b 100644 (file)
 
 IMPLEMENT_STANDARD_RTTIEXT(ShapeAnalysis_Surface,Standard_Transient)
 
+namespace
+{
+  inline void RestrictBounds (double& theFirst, double& theLast)
+  {
+    Standard_Boolean isFInf = Precision::IsNegativeInfinite(theFirst);
+    Standard_Boolean isLInf = Precision::IsPositiveInfinite(theLast);
+    if (isFInf || isLInf)
+    {
+      if (isFInf && isLInf)
+      {
+        theFirst = -1000;
+        theLast = 1000;
+      }
+      else if (isFInf)
+      {
+        theFirst = theLast - 2000;
+      }
+      else
+      {
+        theLast = theFirst + 2000;
+      }
+    }
+  }
+
+  inline void RestrictBounds (double& theUf, double& theUl, double& theVf, double& theVl)
+  {
+    RestrictBounds (theUf, theUl);
+    RestrictBounds (theVf, theVl);
+  }
+}
+
 //S4135
 //S4135
 //=======================================================================
@@ -540,15 +571,9 @@ Standard_Boolean ShapeAnalysis_Surface::IsUClosed(const Standard_Real preci)
     Standard_Real uf, ul, vf, vl;
     Bounds(uf, ul, vf, vl);//modified by rln on 12/11/97 mySurf-> is deleted
     //mySurf->Bounds (uf,ul,vf,vl);
-    if (Precision::IsInfinite(uf) || Precision::IsInfinite(ul))
-    {
-      myUDelt = 0.;
-    }
-    else
-    {
-      myUDelt = Abs(ul - uf) / 20;//modified by rln 11/11/97 instead of 10
-                                  //because of the example when 10 was not enough
-    }
+    RestrictBounds (uf, ul, vf, vl);
+    myUDelt = Abs(ul - uf) / 20;//modified by rln 11/11/97 instead of 10
+                                //because of the example when 10 was not enough
     if (mySurf->IsUClosed())
     {
       myUCloseVal = 0.;
@@ -759,15 +784,9 @@ Standard_Boolean ShapeAnalysis_Surface::IsVClosed(const Standard_Real preci)
     Standard_Real uf, ul, vf, vl;
     Bounds(uf, ul, vf, vl);//modified by rln on 12/11/97 mySurf-> is deleted
                            //    mySurf->Bounds (uf,ul,vf,vl);
-    if (Precision::IsInfinite(vf) || Precision::IsInfinite(vl))
-    {
-      myVDelt = 0.;
-    }
-    else
-    {
-      myVDelt = Abs(vl - vf) / 20;// 2; rln S4135
-                                  //because of the example when 10 was not enough
-    }
+    RestrictBounds (uf, ul, vf, vl);
+    myVDelt = Abs(vl - vf) / 20;// 2; rln S4135
+                                //because of the example when 10 was not enough
     if (mySurf->IsVClosed())
     {
       myVCloseVal = 0.;
@@ -1192,10 +1211,7 @@ gp_Pnt2d ShapeAnalysis_Surface::ValueOfUV(const gp_Pnt& P3D, const Standard_Real
           ul = 500;
         }
 
-        if (Precision::IsInfinite(uf)) uf = -1000;
-        if (Precision::IsInfinite(ul)) ul = 1000;
-        if (Precision::IsInfinite(vf)) vf = -1000;
-        if (Precision::IsInfinite(vl)) vl = 1000;
+        RestrictBounds (uf, ul, vf, vl);
 
         //:30 by abv 2.12.97: speed optimization
         // code is taken from GeomAPI_ProjectPointOnSurf
@@ -1417,8 +1433,7 @@ Standard_Real ShapeAnalysis_Surface::UVFromIso(const gp_Pnt& P3d, const Standard
           Cf = iso->FirstParameter();
           Cl = iso->LastParameter();
 
-          if (Precision::IsInfinite(Cf))  Cf = -1000;
-          if (Precision::IsInfinite(Cl))  Cl = +1000;
+          RestrictBounds (Cf, Cl);
           dist = ShapeAnalysis_Curve().Project(iso, P3d, preci, pntres, other, Cf, Cl, Standard_False);
           if (dist < theMin) {
             theMin = dist;
@@ -1464,8 +1479,7 @@ Standard_Real ShapeAnalysis_Surface::UVFromIso(const gp_Pnt& P3d, const Standard
         if (!iso.IsNull()) {
           Cf = iso->FirstParameter();
           Cl = iso->LastParameter();
-          if (Precision::IsInfinite(Cf))  Cf = -1000;
-          if (Precision::IsInfinite(Cl))  Cl = +1000;
+          RestrictBounds (Cf, Cl);
           dist = ShapeAnalysis_Curve().Project(iso, P3d, preci, pntres, other, Cf, Cl, Standard_False);
           if (dist < theMin) {
             theMin = dist;
@@ -1478,8 +1492,7 @@ Standard_Real ShapeAnalysis_Surface::UVFromIso(const gp_Pnt& P3d, const Standard
         if (!iso.IsNull()) {
           Cf = iso->FirstParameter();
           Cl = iso->LastParameter();
-          if (Precision::IsInfinite(Cf))  Cf = -1000;
-          if (Precision::IsInfinite(Cl))  Cl = +1000;
+          RestrictBounds (Cf, Cl);
           dist = ShapeAnalysis_Curve().Project(iso, P3d, preci, pntres, other, Cf, Cl, Standard_False);
           if (dist < theMin) {
             theMin = dist;
@@ -1504,8 +1517,7 @@ Standard_Real ShapeAnalysis_Surface::UVFromIso(const gp_Pnt& P3d, const Standard
         }
         Cf = anIsoCurve.FirstParameter();
         Cl = anIsoCurve.LastParameter();
-        if (Precision::IsInfinite(Cf))  Cf = -1000;
-        if (Precision::IsInfinite(Cl))  Cl = +1000;
+        RestrictBounds (Cf, Cl);
         dist = ShapeAnalysis_Curve().Project(anIsoCurve, P3d, preci, pntres, other);
         if (dist < theMin) {
           theMin = dist;
@@ -1522,8 +1534,7 @@ Standard_Real ShapeAnalysis_Surface::UVFromIso(const gp_Pnt& P3d, const Standard
         }
         Cf = anIsoCurve.FirstParameter();
         Cl = anIsoCurve.LastParameter();
-        if (Precision::IsInfinite(Cf))  Cf = -1000;
-        if (Precision::IsInfinite(Cl))  Cl = +1000;
+        RestrictBounds (Cf, Cl);
         dist = ShapeAnalysis_Curve().ProjectAct(anIsoCurve, P3d, preci, pntres, other);
         if (dist < theMin) {
           theMin = dist;
diff --git a/tests/bugs/modalg_7/bug30679 b/tests/bugs/modalg_7/bug30679
new file mode 100644 (file)
index 0000000..0461101
--- /dev/null
@@ -0,0 +1,12 @@
+puts "========"
+puts "0030679: Attached model hangs most of OCCT common functionality"
+puts "========"
+puts ""
+
+puts "REQUIRED ALL: Evaluation of infinite parameters"
+restore [locate_data_file bug30679_face.brep] a
+
+pcurve a
+2dcvalue a_4 1 u v
+mksurface s a
+catch {svalue s u v x y z}