0030273: Modeling Algorithms - Crash in postprocessing of imported shape.
authorika <ika@opencascade.com>
Fri, 19 Oct 2018 13:45:18 +0000 (16:45 +0300)
committerapn <apn@opencascade.com>
Fri, 30 Nov 2018 10:39:16 +0000 (13:39 +0300)
Now end points of intervals calculated in GeomAdapter_Curve are not replaced by GeomAdapter_Surface.
Left bound of periodic curve less than UMin is not corrupted by LocateParameter during intervals calculating.

src/GeomAdaptor/GeomAdaptor_Curve.cxx
src/GeomAdaptor/GeomAdaptor_Surface.cxx
tests/bugs/modalg_7/bug30273 [new file with mode: 0644]

index 89f9f57..390673c 100644 (file)
@@ -300,7 +300,14 @@ Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
           BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myLast,
                                     myBSplineCurve->IsPeriodic(),
                                     1,Nb,Index2,newLast);
-
+          // Protection against myFirst = UFirst - eps, which located as ULast - eps
+          if (myBSplineCurve->IsPeriodic() && (newLast - newFirst) < Precision::PConfusion())
+          {
+            if (Abs(newLast - myBSplineCurve->FirstParameter()) < Precision::PConfusion())
+              newLast += myBSplineCurve->Period();
+            else
+              newFirst -= myBSplineCurve->Period();
+          }
           // On decale eventuellement les indices  
           // On utilise une "petite" tolerance, la resolution ne doit 
           // servir que pour les tres longue courbes....(PRO9248)
@@ -425,26 +432,36 @@ void GeomAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
                                      1,Nb,Index2,newLast);
             FirstParam = newFirst;
             LastParam = newLast;
+            // Protection against myFirst = UFirst - eps, which located as ULast - eps
+            if (myBSplineCurve->IsPeriodic() && (LastParam - FirstParam) < Precision::PConfusion())
+            {
+              if (Abs(LastParam - myBSplineCurve->FirstParameter()) < Precision::PConfusion())
+                LastParam += myBSplineCurve->Period();
+              else
+                FirstParam -= myBSplineCurve->Period();
+            }
            // On decale eventuellement les indices  
            // On utilise une "petite" tolerance, la resolution ne doit 
            // servir que pour les tres longue courbes....(PRO9248)
            Standard_Real Eps = Min(Resolution(Precision::Confusion()),
                                    Precision::PConfusion()); 
-           if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++;
-           if ( newLast-TK(Index2)> Eps) Index2++;
+           if ( Abs(FirstParam-TK(Index1+1))< Eps) Index1++;
+           if ( LastParam-TK(Index2)> Eps) Index2++;
            
-           Inter( 1) = Index1;
            myNbIntervals = 1;
+
+            TColStd_Array1OfInteger aFinalIntervals(1, Inter.Upper());
+            aFinalIntervals(1) = Index1;
            for ( Standard_Integer i=1; i<=NbInt; i++) {
              if (Inter(i) > Index1 && Inter(i)<Index2 ) {
                myNbIntervals++;
-               Inter(myNbIntervals) = Inter(i);
+                aFinalIntervals(myNbIntervals) = Inter(i);
              }
            }
-           Inter(myNbIntervals+1) = Index2;
+            aFinalIntervals(myNbIntervals + 1) = Index2;
            
            for (Standard_Integer I=1;I<=myNbIntervals+1;I++) {
-             T(I) = TK(Inter(I));
+              T(I) = TK(aFinalIntervals(I));
            }
          }
          break;
index ff860f6..621220d 100644 (file)
@@ -438,7 +438,7 @@ void GeomAdaptor_Surface::UIntervals(TColStd_Array1OfReal& T, const GeomAbs_Shap
         (myBSplineSurface->VIso(myBSplineSurface->VKnot(myBSplineSurface->FirstVKnotIndex())),myUFirst,myULast);
       myNbUIntervals = myBasisCurve.NbIntervals(S);
       myBasisCurve.Intervals(T,S);
-      break;
+      return;
     }
     case GeomAbs_SurfaceOfExtrusion:
     {
@@ -448,6 +448,7 @@ void GeomAdaptor_Surface::UIntervals(TColStd_Array1OfReal& T, const GeomAbs_Shap
       {
         myNbUIntervals = myBasisCurve.NbIntervals(S);
         myBasisCurve.Intervals(T,S);
+        return;
       }
       break;
     }
@@ -468,6 +469,7 @@ void GeomAdaptor_Surface::UIntervals(TColStd_Array1OfReal& T, const GeomAbs_Shap
       GeomAdaptor_Surface Sur(myOffSurf->BasisSurface(), myUFirst, myULast, myVFirst, myVLast);
       myNbUIntervals = Sur.NbUIntervals(BaseS);
       Sur.UIntervals(T, BaseS);
+      return;
     }
     case GeomAbs_Plane:
     case GeomAbs_Cylinder:
@@ -500,7 +502,7 @@ void GeomAdaptor_Surface::VIntervals(TColStd_Array1OfReal& T, const GeomAbs_Shap
         (myBSplineSurface->UIso(myBSplineSurface->UKnot(myBSplineSurface->FirstUKnotIndex())),myVFirst,myVLast);
       myNbVIntervals = myBasisCurve.NbIntervals(S);
       myBasisCurve.Intervals(T,S);
-      break;
+      return;
     }
     case GeomAbs_SurfaceOfRevolution:
     {
@@ -511,6 +513,7 @@ void GeomAdaptor_Surface::VIntervals(TColStd_Array1OfReal& T, const GeomAbs_Shap
       {
         myNbVIntervals = myBasisCurve.NbIntervals(S);
         myBasisCurve.Intervals(T,S);
+        return;
       }
       break;
     }
@@ -531,6 +534,7 @@ void GeomAdaptor_Surface::VIntervals(TColStd_Array1OfReal& T, const GeomAbs_Shap
       GeomAdaptor_Surface Sur(myOffSurf->BasisSurface(), myUFirst, myULast, myVFirst, myVLast);
       myNbVIntervals = Sur.NbVIntervals(BaseS);
       Sur.VIntervals(T, BaseS);
+      return;
     }
     case GeomAbs_Plane:
     case GeomAbs_Cylinder:
diff --git a/tests/bugs/modalg_7/bug30273 b/tests/bugs/modalg_7/bug30273
new file mode 100644 (file)
index 0000000..4c29c1c
--- /dev/null
@@ -0,0 +1,9 @@
+puts "========"
+puts "0030273: Crash in postprocessing of imported shape."
+puts "========"
+puts ""
+
+pload XDE
+
+stepread [locate_data_file bug30273.stp] res *
+checknbshapes res_1 -solid 176 -face 9968 -shape 69497