]> OCCT Git - occt.git/commitdiff
0031995: Modeling Data - Bounding box wrong for face
authorifv <ifv@opencascade.com>
Wed, 9 Dec 2020 14:28:37 +0000 (17:28 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 17 Dec 2020 18:17:44 +0000 (21:17 +0300)
BndLib/BndLib_AddSurface.cxx : algorithm of building bounding box for BSpline surfaces is improved

Test cases are modified according to current state of algorithm
Test case bug31995 added

src/BndLib/BndLib_AddSurface.cxx
tests/bugs/iges/buc60823
tests/bugs/mesh/bug30008_1
tests/bugs/moddata_3/bug25631
tests/bugs/moddata_3/bug31995 [new file with mode: 0644]
tests/hlr/poly_hlr/C14

index 15c18ea833f9c608ca565cc576e18a285c5b875e..d1da6be0f171c245ed353315c77606ba64a607ed 100644 (file)
@@ -60,6 +60,17 @@ static Standard_Real  AdjustExtr(const Adaptor3d_Surface& S,
                                  const Standard_Real Tol, 
                                  const Standard_Boolean IsMin);
 
+
+static void ComputePolesIndexes(const TColStd_Array1OfReal &theKnots,
+  const TColStd_Array1OfInteger &theMults,
+  const Standard_Integer theDegree,
+  const Standard_Real theMin,
+  const Standard_Real theMax,
+  const Standard_Integer theMaxPoleIdx,
+  const Standard_Boolean theIsPeriodic,
+  Standard_Integer &theOutMinIdx,
+  Standard_Integer &theOutMaxIdx);
+
 //=======================================================================
 //function : Add
 //purpose  : 
@@ -212,35 +223,31 @@ static void TreatInfinitePlane(const gp_Pln        &aPlane,
 // theShiftCoeff - shift between flatknots array and poles array.
 // This vaule should be equal to 1 in case of non periodic BSpline,
 // and (degree + 1) - mults(the lowest index).
-void ComputePolesIndexes(const TColStd_Array1OfReal &theFlatKnots,
-                         const Standard_Integer theDegree,
-                         const Standard_Real theMin,
-                         const Standard_Real theMax,
-                         const Standard_Integer theMinIdx,
-                         const Standard_Integer theMaxIdx,
-                         const Standard_Integer theShiftCoeff,
-                         Standard_Integer &theOutMinIdx,
-                         Standard_Integer &theOutMaxIdx)
-{
-  // Set initial values for the result indexes to handle situation when requested parameter space
-  // is slightly greater than B-spline parameter space.
-  theOutMinIdx = theFlatKnots.Lower();
-  theOutMaxIdx = theFlatKnots.Upper();
-
-  // Compute first and last used flat knots.
-  for(Standard_Integer aKnotIdx = theFlatKnots.Lower();
-      aKnotIdx < theFlatKnots.Upper();
-      aKnotIdx++)
-  {
-    if (theFlatKnots(aKnotIdx) <= theMin)
-      theOutMinIdx = aKnotIdx;
 
-    if (theFlatKnots(theFlatKnots.Upper() - aKnotIdx + theFlatKnots.Lower()) >= theMax)
-      theOutMaxIdx = theFlatKnots.Upper() - aKnotIdx + theFlatKnots.Lower();
-  }
-
-  theOutMinIdx = Max(theOutMinIdx - 2 * theDegree + 2 - theShiftCoeff, theMinIdx);
-  theOutMaxIdx = Min(theOutMaxIdx - 2 + theDegree + 1 - theShiftCoeff, theMaxIdx);
+void ComputePolesIndexes(const TColStd_Array1OfReal &theKnots,
+  const TColStd_Array1OfInteger &theMults,
+  const Standard_Integer theDegree,
+  const Standard_Real theMin,
+  const Standard_Real theMax,
+  const Standard_Integer theMaxPoleIdx,
+  const Standard_Boolean theIsPeriodic,
+  Standard_Integer &theOutMinIdx,
+  Standard_Integer &theOutMaxIdx)
+{
+  BSplCLib::Hunt(theKnots, theMin, theOutMinIdx);
+  theOutMinIdx = Max(theOutMinIdx, theKnots.Lower());
+
+  BSplCLib::Hunt(theKnots, theMax, theOutMaxIdx);
+  theOutMaxIdx++;
+  theOutMaxIdx = Min(theOutMaxIdx, theKnots.Upper());
+  Standard_Integer mult = theMults(theOutMaxIdx);
+
+  theOutMinIdx = BSplCLib::PoleIndex(theDegree, theOutMinIdx, theIsPeriodic, theMults) + 1;
+  theOutMinIdx = Max(theOutMinIdx, 1);
+  theOutMaxIdx = BSplCLib::PoleIndex(theDegree, theOutMaxIdx, theIsPeriodic, theMults) + 1;
+  theOutMaxIdx += theDegree - mult;
+  if (!theIsPeriodic)
+    theOutMaxIdx = Min(theOutMaxIdx, theMaxPoleIdx);
 }
 
 //  Modified by skv - Fri Aug 27 12:29:04 2004 OCC6503 End
@@ -336,6 +343,7 @@ void BndLib_AddSurface::Add(const Adaptor3d_Surface& S,
       // Borders of underlying geometry.
       Standard_Real anUMinParam = UMin, anUMaxParam = UMax,// BSpline case.
                      aVMinParam = VMin,  aVMaxParam = VMax;
+      Handle(Geom_BSplineSurface) aBS;
       if (Type == GeomAbs_BezierSurface)
       {
         // Bezier surface:
@@ -358,8 +366,8 @@ void BndLib_AddSurface::Add(const Adaptor3d_Surface& S,
         // use convex hull algorithm,
         // if Umin, VMin, Umax, Vmax lies outside then:
         // use grid algorithm on analytic continuation (default case).
-        S.BSpline()->Bounds(anUMinParam, anUMaxParam, aVMinParam, aVMaxParam);
-
+        aBS = S.BSpline();
+        aBS->Bounds(anUMinParam, anUMaxParam, aVMinParam, aVMaxParam);
         if ( (UMin - anUMinParam) < -PTol ||
              (VMin -  aVMinParam) < -PTol ||
              (UMax - anUMaxParam) >  PTol ||
@@ -372,94 +380,87 @@ void BndLib_AddSurface::Add(const Adaptor3d_Surface& S,
 
       if (isUseConvexHullAlgorithm)
       {
-          TColgp_Array2OfPnt Tp(1,S.NbUPoles(),1,S.NbVPoles());
-          Standard_Integer UMinIdx = 0, UMaxIdx = 0;
-          Standard_Integer VMinIdx = 0, VMaxIdx = 0;
-          if (Type == GeomAbs_BezierSurface)
-          {
-            S.Bezier()->Poles(Tp);
+        Standard_Integer aNbUPoles = S.NbUPoles(), aNbVPoles = S.NbVPoles();
+        TColgp_Array2OfPnt Tp(1, aNbUPoles, 1, aNbVPoles);
+        Standard_Integer UMinIdx = 0, UMaxIdx = 0;
+        Standard_Integer VMinIdx = 0, VMaxIdx = 0;
+        Standard_Boolean isUPeriodic = S.IsUPeriodic(), isVPeriodic = S.IsVPeriodic();
+        if (Type == GeomAbs_BezierSurface)
+        {
+          S.Bezier()->Poles(Tp);
+          UMinIdx = 1; UMaxIdx = aNbUPoles;
+          VMinIdx = 1; VMaxIdx = aNbVPoles;
+        }
+        else
+        {
+          aBS->Poles(Tp);
 
-            UMinIdx = Tp.LowerRow();
-            UMaxIdx = Tp.UpperRow();
-            VMinIdx = Tp.LowerCol();
-            VMaxIdx = Tp.UpperCol();
-          }
-          else
+          UMinIdx = 1;
+          UMaxIdx = aNbUPoles;
+          VMinIdx = 1;
+          VMaxIdx = aNbVPoles;
+
+          if (UMin > anUMinParam ||
+              UMax < anUMaxParam)
           {
-            S.BSpline()->Poles(Tp);
+            TColStd_Array1OfInteger aMults(1, aBS->NbUKnots());
+            TColStd_Array1OfReal aKnots(1, aBS->NbUKnots());
+            aBS->UKnots(aKnots);
+            aBS->UMultiplicities(aMults);
+
+            ComputePolesIndexes(aKnots,
+              aMults,
+              aBS->UDegree(),
+              UMin, UMax,
+              aNbUPoles,
+              isUPeriodic,
+              UMinIdx, UMaxIdx); // the Output indexes
 
-            UMinIdx = Tp.LowerRow();
-            UMaxIdx = Tp.UpperRow();
-            VMinIdx = Tp.LowerCol();
-            VMaxIdx = Tp.UpperCol();
+          }
 
-            if (UMin > anUMinParam ||
-                UMax < anUMaxParam)
-            {
-              Standard_Integer anUFlatKnotsCount = S.BSpline()->NbUPoles() + S.BSpline()->UDegree() + 1;
-              Standard_Integer aShift = 1;
-
-              if (S.BSpline()->IsUPeriodic())
-              {
-                TColStd_Array1OfInteger aMults(1, S.BSpline()->NbUKnots());
-                S.BSpline()->UMultiplicities(aMults);
-                anUFlatKnotsCount = BSplCLib::KnotSequenceLength(aMults, S.BSpline()->UDegree(), Standard_True);
-
-                aShift = S.BSpline()->UDegree() + 1 - S.BSpline()->UMultiplicity(1);
-              }
-
-              TColStd_Array1OfReal anUFlatKnots(1, anUFlatKnotsCount);
-              S.BSpline()->UKnotSequence(anUFlatKnots);
-
-              ComputePolesIndexes(anUFlatKnots,
-                                  S.BSpline()->UDegree(),
-                                  UMin, UMax,
-                                  UMinIdx, UMaxIdx,  // Min and Max Indexes
-                                  aShift,
-                                  UMinIdx, UMaxIdx); // the Output indexes
-            }
+          if (VMin > aVMinParam ||
+            VMax < aVMaxParam)
+          {
+            TColStd_Array1OfInteger aMults(1, aBS->NbVKnots());
+            TColStd_Array1OfReal aKnots(1, aBS->NbVKnots());
+            aBS->VKnots(aKnots);
+            aBS->VMultiplicities(aMults);
+
+            ComputePolesIndexes(aKnots,
+              aMults,
+              aBS->VDegree(),
+              VMin, VMax,
+              aNbVPoles,
+              isVPeriodic,
+              VMinIdx, VMaxIdx); // the Output indexes
+          }
 
-            if (VMin > aVMinParam ||
-                VMax < aVMaxParam)
-            {
-              Standard_Integer anVFlatKnotsCount = S.BSpline()->NbVPoles() + S.BSpline()->VDegree() + 1;
-              Standard_Integer aShift = 1;
-
-              if (S.BSpline()->IsVPeriodic())
-              {
-                TColStd_Array1OfInteger aMults(1, S.BSpline()->NbVKnots());
-                S.BSpline()->VMultiplicities(aMults);
-                anVFlatKnotsCount = BSplCLib::KnotSequenceLength(aMults, S.BSpline()->VDegree(), Standard_True);
-
-                aShift = S.BSpline()->VDegree() + 1 - S.BSpline()->VMultiplicity(1);
-              }
-
-              TColStd_Array1OfReal anVFlatKnots(1, anVFlatKnotsCount);
-              S.BSpline()->VKnotSequence(anVFlatKnots);
-
-              ComputePolesIndexes(anVFlatKnots,
-                                  S.BSpline()->VDegree(),
-                                  VMin, VMax,
-                                  VMinIdx, VMaxIdx,  // Min and Max Indexes
-                                  aShift,
-                                  VMinIdx, VMaxIdx); // the Output indexes
-            }
+        }
 
+        // Use poles to build convex hull.
+        Standard_Integer ip, jp;
+        for (Standard_Integer i = UMinIdx; i <= UMaxIdx; i++)
+        {
+          ip = i;
+          if (isUPeriodic && ip > aNbUPoles)
+          {
+            ip = ip - aNbUPoles;
           }
-
-          // Use poles to build convex hull.
-          for (Standard_Integer i = UMinIdx; i <= UMaxIdx; i++)
+          for (Standard_Integer j = VMinIdx; j <= VMaxIdx; j++)
           {
-            for (Standard_Integer j = VMinIdx; j <= VMaxIdx; j++)
+            jp = j;
+            if (isVPeriodic && jp > aNbVPoles)
             {
-              B.Add(Tp(i,j));
+              jp = jp - aNbVPoles;
             }
+            B.Add(Tp(ip, jp));
           }
+        }
 
-          B.Enlarge(Tol);
-          break;
+        B.Enlarge(Tol);
+        break;
       }
-    }
+  }
     Standard_FALLTHROUGH
   default: 
     {
@@ -961,7 +962,7 @@ Standard_Integer NbVSamples(const Adaptor3d_Surface& S,
     {
       const Handle(Geom_BSplineSurface)& BS = S.BSpline();
       N = 2*(BS->VDegree() + 1)*(BS->NbVKnots() - 1) ;
-     Standard_Real umin, umax, vmin, vmax;
+      Standard_Real umin, umax, vmin, vmax;
       BS->Bounds(umin, umax, vmin, vmax);
       Standard_Real dv = (Vmax - Vmin) / (vmax - vmin);
       if(dv < .9)
index b20f3bc60c9140fb4d20bc8a5d94364cc00b0aff..e80b533a8688ad919ca1ea1ba794f7b060f52307 100755 (executable)
@@ -14,6 +14,6 @@ vdisplay result
 vsetdispmode result 1
 vfit
 
-checktrinfo result -tri 2711 -nod 2611
+checktrinfo result -tri 2722 -nod 2618
 
 checkview -display result -2d -path ${imagedir}/${test_image}.png
index 1beebc5f401fcfed035b7bf083f7d2d84a7fd2b4..5b1393cc940e1ab8d97e2320faf9650a77a1cd04 100644 (file)
@@ -12,6 +12,6 @@ vdisplay result
 vviewparams -scale 8.46292 -proj 0.653203 -0.644806 0.396926 -up -0.0109833 0.51609 0.856464 -at 347.559 1026.89 219.262 -eye 2080.75 -684.022 1272.45
 
 tricheck result
-checktrinfo result -tri 11826 -nod 7310 -defl 7.6167024939147652
+checktrinfo result -tri 11800 -nod 7301 -defl 7.6167024939147652
 
 checkview -screenshot -3d -path ${imagedir}/${test_image}.png
index b3c8d48c1dba456de4db3b3fcd476ed2c74af8aa..1e1dfa7c97e1cdec6b2769ada43349ad1061e596 100755 (executable)
@@ -13,12 +13,12 @@ bounding result -save Xmin Ymin Zmin Xmax Ymax Zmax
 set tol_abs 1.0e-4
 set tol_rel 1.0e-4
 
-checkreal "Xmin" [dval Xmin]  102.04999989999993 ${tol_abs} ${tol_rel}
-checkreal "Ymin" [dval Ymin] -12.576503364721431 ${tol_abs} ${tol_rel}
-checkreal "Zmin" [dval Zmin] -12.267407382031644 ${tol_abs} ${tol_rel}
-checkreal "Xmax" [dval Xmax] 145.65000009999983 ${tol_abs} ${tol_rel}
-checkreal "Ymax" [dval Ymax] 1.0883692081680807 ${tol_abs} ${tol_rel}
-checkreal "Zmax" [dval Zmax] 1.4146362604116396 ${tol_abs} ${tol_rel}
+checkreal "Xmin" [dval Xmin]  107.49999989999992 ${tol_abs} ${tol_rel}
+checkreal "Ymin" [dval Ymin] -12.487307730633276 ${tol_abs} ${tol_rel}
+checkreal "Zmin" [dval Zmin] -12.135364833115547 ${tol_abs} ${tol_rel}
+checkreal "Xmax" [dval Xmax]  140.20000009999987 ${tol_abs} ${tol_rel}
+checkreal "Ymax" [dval Ymax] -0.8336837432205401 ${tol_abs} ${tol_rel}
+checkreal "Zmax" [dval Zmax] -0.5631589698265231 ${tol_abs} ${tol_rel}
 
 smallview
 fit
diff --git a/tests/bugs/moddata_3/bug31995 b/tests/bugs/moddata_3/bug31995
new file mode 100644 (file)
index 0000000..4bd9883
--- /dev/null
@@ -0,0 +1,23 @@
+puts "========="
+puts "0031995: Modeling Data - Bounding box wrong for face"
+puts "========="
+puts ""
+
+
+restore [locate_data_file bug31995.brep] result
+
+bounding result -save Xmin Ymin Zmin Xmax Ymax Zmax
+
+set tol_abs 1.0e-4
+set tol_rel 1.0e-4
+
+checkreal "Xmin" [dval Xmin] -0.4992512824357961 ${tol_abs} ${tol_rel}
+checkreal "Ymin" [dval Ymin]  0.5646627848871493 ${tol_abs} ${tol_rel}
+checkreal "Zmin" [dval Zmin]  0.5646627848871487 ${tol_abs} ${tol_rel}
+checkreal "Xmax" [dval Xmax]  0.1535534905932737 ${tol_abs} ${tol_rel}
+checkreal "Ymax" [dval Ymax]  1.4505295939775213 ${tol_abs} ${tol_rel}
+checkreal "Zmax" [dval Zmax]  1.4505295939775207 ${tol_abs} ${tol_rel}
+
+smallview
+fit
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
index 857e48713261f56e74fb24d355937e9b4cdac929..24b76c56f6e547e8619fdca8788535b8cfbce8e5 100644 (file)
@@ -1,4 +1,4 @@
-puts "TODO OCC30286 ALL: Error : The length of result shape is 5496.05, expected 5934.34"
+puts "TODO OCC30286 ALL: Error : The length of result shape is 5499.57, expected 5934.34"
 
 set viewname "vright"
 set length 5934.34