diff --git a/src/GeomEvaluator/GeomEvaluator_OffsetSurface.cxx b/src/GeomEvaluator/GeomEvaluator_OffsetSurface.cxx index d2fcead403..b115be3f47 100644 --- a/src/GeomEvaluator/GeomEvaluator_OffsetSurface.cxx +++ b/src/GeomEvaluator/GeomEvaluator_OffsetSurface.cxx @@ -23,6 +23,7 @@ #include #include #include +#include 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); diff --git a/src/ShapeAnalysis/ShapeAnalysis_Surface.cxx b/src/ShapeAnalysis/ShapeAnalysis_Surface.cxx index 2efd9c0c33..93c2d0f892 100644 --- a/src/ShapeAnalysis/ShapeAnalysis_Surface.cxx +++ b/src/ShapeAnalysis/ShapeAnalysis_Surface.cxx @@ -60,6 +60,37 @@ 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 index 0000000000..0461101753 --- /dev/null +++ b/tests/bugs/modalg_7/bug30679 @@ -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}