]> OCCT Git - occt-copy.git/commitdiff
0029745: Modeling Data - GeomAdaptor_Surface::VIntervals fails on periodic surfaces
authorakaftasev <akaftasev@opencascade.com>
Fri, 15 Jan 2021 07:50:18 +0000 (10:50 +0300)
committerakaftasev <akaftasev@opencascade.com>
Tue, 16 Feb 2021 09:04:15 +0000 (12:04 +0300)
Fixed GeomAdaptor_Curve::LocalContinuity() for periodic surface within one period
Fixed GeomAdaptor_Curve::NbIntervals() method to periodic curves
Fixed GeomAdaptor_Curve::Intervals() method to periodic curves

14 files changed:
src/GeomAdaptor/GeomAdaptor_Curve.cxx
src/QABugs/QABugs_20.cxx
tests/bugs/modalg_6/bug25908
tests/hlr/exact_hlr/A1
tests/hlr/exact_hlr/C20
tests/hlr/exact_hlr/D4
tests/hlr/exact_hlr/D5
tests/hlr/poly_hlr/A1
tests/hlr/poly_hlr/A2
tests/hlr/poly_hlr/A3
tests/hlr/poly_hlr/A4
tests/hlr/poly_hlr/A5
tests/hlr/poly_hlr/A6
tests/hlr/poly_hlr/A7

index 6d8bfae8122096f354047b8a8e558cd12f1c5137..dccbbf5f0eaa2a3fbc3287b05278d8ded1f08fd3 100644 (file)
@@ -90,23 +90,33 @@ GeomAbs_Shape GeomAdaptor_Curve::LocalContinuity(const Standard_Real U1,
   if ( Abs(newFirst-TK(Index1+1))<Precision::PConfusion()) { 
     if (Index1 < Nb) Index1++;
   }
-  if ( Abs(newLast-TK(Index2))<Precision::PConfusion())
+  if (Abs(newLast - TK(Index2)) < Precision::PConfusion())
     Index2--;
-  Standard_Integer MultMax;
-  // attention aux courbes peridiques.
-  if ( (myBSplineCurve->IsPeriodic()) && (Index1 == Nb) )
-    Index1 = 1;
+  Standard_Integer MultMax;  
 
-  if ( Index2 - Index1 <= 0) {
+  if (myBSplineCurve->IsPeriodic())
+  {
+    if (Index1 == Nb)
+    {
+      Index1 = 1;
+    }
+    if (Index2 == 0)
+    {
+      Index2 = Nb;
+    }
+  }
+
+  if (Index2 - Index1 <= 0) {
     MultMax = 100;  // CN entre 2 Noeuds consecutifs
   }
   else {
-    MultMax = TM(Index1+1);
-    for(Standard_Integer i = Index1+1;i<=Index2;i++) {
-      if ( TM(i)>MultMax) MultMax=TM(i);
+    MultMax = TM(Index1 + 1);
+    for (Standard_Integer i = Index1 + 1; i <= Index2; i++) {
+      if (TM(i) > MultMax) MultMax = TM(i);
     }
     MultMax = myBSplineCurve->Degree() - MultMax;
   }
+  
   if ( MultMax <= 0) {
     return GeomAbs_C0;
   }
@@ -246,6 +256,7 @@ Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
   if (myTypeCurve == GeomAbs_BSplineCurve) {
     Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex();
     Standard_Integer LastIndex  = myBSplineCurve->LastUKnotIndex();
+    Standard_Boolean isPeriodic = myBSplineCurve->IsPeriodic();
     TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
     if ( S > Continuity()) {
       Standard_Integer Cont;
@@ -271,11 +282,11 @@ Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
           TColStd_Array1OfInteger Mults (1, NbKnots);
           myBSplineCurve->Multiplicities (Mults);
           NbSplit = 1;
-          Standard_Integer Index   = FirstIndex;
+          Standard_Integer Index = FirstIndex;
           Inter (NbSplit) = Index;
           Index++;
           NbSplit++;
-          while (Index < LastIndex) 
+          while (Index < LastIndex)
             {
              if (Degree - Mults (Index) < Cont) 
                {
@@ -300,14 +311,7 @@ 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)
@@ -316,9 +320,38 @@ Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
           if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++;
           if ( newLast-TK(Index2)> Eps) Index2++;
           
+          if (myBSplineCurve->IsPeriodic())
+          {
+            if (Index1 == Nb)
+            {
+              Index1 = 1;
+            }
+            if (Index2 == 1)
+            {
+              Index2 = Nb;
+            }
+          }
+
           myNbIntervals = 1;
-          for ( Standard_Integer i=1; i<=NbInt; i++)
-            if (Inter(i)>Index1 && Inter(i)<Index2) myNbIntervals++;
+
+
+          //   Calculating number of intervals if myBSplineCurve->IsPeriodic()
+            //    |>----|....|---->|
+            //       Index2 Index1  
+            //    |     Period     |
+          for (Standard_Integer i = 1; i <= NbInt; i++) {
+            if (isPeriodic && (Index1 >= Index2))
+            {
+              if ((Inter(i) > Index1 && Inter(i) < Nb) || (Inter(i) > 0 && Inter(i) < Index2))
+              {
+                myNbIntervals++;
+              }
+            }
+            else if (Inter(i) > Index1 && Inter(i) < Index2)
+            {
+              myNbIntervals++;
+            }
+          }
         }
         break;
       }
@@ -372,6 +405,7 @@ void GeomAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
     {
       Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex();
       Standard_Integer LastIndex  = myBSplineCurve->LastUKnotIndex();
+      Standard_Boolean isPeriodic = myBSplineCurve->IsPeriodic();
       TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
       
       if ( S > Continuity()) {
@@ -425,21 +459,14 @@ void GeomAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
             const TColStd_Array1OfReal& TK = myBSplineCurve->Knots();
             const TColStd_Array1OfInteger& TM = myBSplineCurve->Multiplicities();
            BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myFirst,
-                                     myBSplineCurve->IsPeriodic(),
+                                      isPeriodic,
                                      1,Nb,Index1,newFirst);
            BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myLast,
-                                     myBSplineCurve->IsPeriodic(),
+                                      isPeriodic,
                                      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)
@@ -448,23 +475,73 @@ void GeomAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
            if ( Abs(FirstParam-TK(Index1+1))< Eps) Index1++;
            if ( LastParam-TK(Index2)> Eps) Index2++;
            
+            if (myBSplineCurve->IsPeriodic())
+            {
+              if (Index1 == Nb)
+              {
+                Index1 = 1;
+              }
+              if (Index2 == 1)
+              {
+                Index2 = Nb;
+              }
+            }
+
            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++;
-                aFinalIntervals(myNbIntervals) = Inter(i);
-             }
-           }
-            aFinalIntervals(myNbIntervals + 1) = Index2;
+
+            //   Calculating number of intervals if myBSplineCurve->IsPeriodic()
+            //    |>----|....|---->|
+            //       Index2 Index1  
+            //    |     Period     |
            
-           for (Standard_Integer I=1;I<=myNbIntervals+1;I++) {
+            if (isPeriodic && (Index1 >= Index2))
+            {
+              for (Standard_Integer i = Index1; i <= NbInt; i++)
+              {
+                if (Inter(i)>Index1 && Inter(i) < Nb)
+                {
+                  myNbIntervals++;
+                  aFinalIntervals(myNbIntervals) = Inter(i);
+                }
+              }
+              for (Standard_Integer i = 1; i <= Index2; i++)
+              {
+                if (Inter(i) > 0 && Inter(i) < Index2)
+                {
+                  myNbIntervals++;
+                  aFinalIntervals(myNbIntervals) = Inter(i);
+                }
+              }
+            }
+            else
+            {
+              for (Standard_Integer i = 1; i <= NbInt; i++)
+              {
+                if (Inter(i) > Index1 && Inter(i) < Index2)
+                {
+                  myNbIntervals++;
+                  aFinalIntervals(myNbIntervals) = Inter(i);
+                }
+              }
+            }
+
+            aFinalIntervals(myNbIntervals + 1) = Index2;
+          
+           for (Standard_Integer I=1;I<=myNbIntervals;I++)
+            {
               T(I) = TK(aFinalIntervals(I));
-           }
-         }
-         break;
+              if (isPeriodic)
+              {
+                T(I) += myBSplineCurve->Period() * Ceiling((myFirst - T(I)) / myBSplineCurve->Period());
+              }
+            }
+          }
+          T(T.Lower()) = myFirst;
+          T(T.Lower() + myNbIntervals) = myLast;
+          return;
        }
       }
     }
index b0ca49f9cc673bc4e8125b11d79ebd81284d701c..53b1ede7acd93d4479e6183ab47968ff8d868d29 100644 (file)
@@ -3885,6 +3885,31 @@ static Standard_Integer QANullifyShape(Draw_Interpretor& di,
   return 0;
 }
 
+static Standard_Integer OCC29745 (Draw_Interpretor& /*theDI*/,
+                                  Standard_Integer /*theNbArgs*/,
+                                  const char** theArgVec)
+{
+  Standard_Integer a1 = Draw::Atoi(theArgVec[1]);
+  Standard_Integer a2 = Draw::Atoi(theArgVec[2]);
+  TColgp_Array2OfPnt Poles(1, 2, 1, 4);
+  Poles(1, 1) = gp_Pnt(0, 0, 0); Poles(2, 1) = gp_Pnt(0, 0, 1);
+  Poles(1, 2) = gp_Pnt(1, 0, 0); Poles(2, 2) = gp_Pnt(1, 0, 1);
+  Poles(1, 3) = gp_Pnt(0, 1, 0); Poles(2, 3) = gp_Pnt(0, 1, 1);
+  Poles(1, 4) = gp_Pnt(1, 1, 0); Poles(2, 4) = gp_Pnt(1, 1, 1);
+  TColStd_Array1OfReal UKnots(1, 2), VKnots(1, 5), ResultsB(1, abs(a1-a2)+1);
+  UKnots(1) = 0; UKnots(2) = 1;
+  VKnots(1) = 0; VKnots(2) = 1; VKnots(3) = 2; VKnots(4) = 3; VKnots(5) = 4;
+  TColStd_Array1OfInteger UMult(1, 2), VMult(1, 5);
+  UMult(1) = 2; UMult(2) = 2;
+  VMult(1) = 1; VMult(2) = 1; VMult(3) = 1; VMult(4) = 1;  VMult(5) = 1;
+  Handle(Geom_BSplineSurface) S = new Geom_BSplineSurface(Poles, UKnots, VKnots, UMult, VMult, 1, 1, false, true);
+  GeomAdaptor_Surface B(S, 0, 1, a1, a2);
+  B.VIntervals(ResultsB, GeomAbs_C1);
+  for (TColStd_Array1OfReal::const_iterator i(ResultsB.begin()); i != ResultsB.end(); ++i) std::cout << *i << " ";
+  std::cout << std::endl;
+  return 0;
+}
+
 void QABugs::Commands_20(Draw_Interpretor& theCommands) {
   const char *group = "QABugs";
 
@@ -3923,7 +3948,7 @@ void QABugs::Commands_20(Draw_Interpretor& theCommands) {
   theCommands.Add("OCC29311", "OCC29311 shape counter nbiter: check performance of OBB calculation", __FILE__, OCC29311, group);
   theCommands.Add("OCC30391", "OCC30391 result face LenBeforeUfirst LenAfterUlast LenBeforeVfirst LenAfterVlast", __FILE__, OCC30391, group);
   theCommands.Add("OCC29195", "OCC29195 [nbRep] doc1 [doc2 [doc3 [doc4]]]", __FILE__, OCC29195, group);
-  theCommands.Add("OCC30435", "OCC30435 result curve inverse nbit", __FILE__, OCC30435, group);
+  theCommands.Add("OCC30435", "OCC30435 result curve invers nbit", __FILE__, OCC30435, group);
   theCommands.Add("OCC30990", "OCC30990 surface", __FILE__, OCC30990, group);
 
   theCommands.Add("QAStartsWith",
@@ -3959,7 +3984,8 @@ void QABugs::Commands_20(Draw_Interpretor& theCommands) {
   theCommands.Add("OCC31785",
                   "OCC31785 file.xbf : test reading XBF file in another thread",
                   __FILE__, OCC31785, group);
-
+  theCommands.Add("OCC29745", "GeomAdaptor_Surface::VIntervals fails on periodic surfaces",
+    __FILE__, OCC29745, group);
 
   theCommands.Add("QANullifyShape",
                   "Nullify shape. Usage: QANullifyShape shape",
index c39131f747b051014421ee022d3762af12630554..8b071c1464f5678f0f758866f303f0490a89fe74 100755 (executable)
@@ -1,3 +1,7 @@
+puts "TODO OCC30286 ALL: Error : HLRToShape is WRONG because number of VERTEX entities in shape "result" is 109"
+puts "TODO OCC30286 ALL: Error : HLRToShape is WRONG because number of EDGE entities in shape "result" is 55"
+puts "TODO OCC30286 ALL: Error : HLRToShape is WRONG because number of SHAPE entities in shape "result" is 165"
+
 puts "============"
 puts "OCC25908"
 puts "============"
index f3f8d3c64e88fceac6d8fecb297e380d06f01827..3da2beb2aa540b0e9addf17764473cf2246127da 100644 (file)
@@ -1,3 +1,5 @@
+puts "TODO OCC30286 ALL: Error : The length of result shape is 6.34983, expected 6.34984"
+
 puts "====================================="
 puts "OCC27341: Incorrect exact HLR results"
 puts "====================================="
index 741d9a04e63ff1192047e029e911623d7cc4cf56..e99fad93e3edfdf070ce6c1493f72e6ec9cddd7e 100644 (file)
@@ -1,4 +1,4 @@
-puts "TODO OCC30286 ALL: Error : The length of result shape is 1736.91, expected 1704.87"
+puts "TODO OCC30286 ALL: Error : The length of result shape is 1736.86, expected 1704.87"
 
 set viewname "vright"
 set length 1704.87
index e76af23e101e91c5d8d0e7db8b5a16dd0e67b6dc..5400f4eed9b9e72a03f5ff2c32f0c8be7e2f7433 100644 (file)
@@ -1,3 +1,5 @@
+puts "TODO OCC30286 ALL: Error : The length of result shape is 484.062, expected 484.485"
+
 puts "============"
 puts "OCC25908"
 puts "============"
index 072138288b019c2cd1dacc8d877fa103ee1e1446..78436b432b3b471cf36da5885455af85a4157189 100644 (file)
@@ -1,3 +1,5 @@
+puts "TODO OCC30286 ALL: Error : The length of result shape is 544.185, expected 544.616"
+
 puts "============"
 puts "OCC25908"
 puts "============"
index 1b6e75a3cc12573daa3bc75c6dde3eeaf0cb0208..ade6131497f9481ddb7f9eadfbdefce2eefb86e5 100644 (file)
@@ -1,3 +1,5 @@
+puts "TODO OCC30286 ALL: Error : The length of result shape is 6.30139, expected 6.30238"
+
 puts "====================================="
 puts "OCC27341: Incorrect exact HLR results"
 puts "====================================="
index c116d9dec93e036a3ecb88d490c38577e2e6bb83..39098da4e62ab7e062449c05105a27a04633ccc6 100644 (file)
@@ -1,4 +1,4 @@
-puts "TODO OCC30286 ALL: Error : The length of result shape is 8.06872, expected 8.05281"
+puts "TODO OCC30286 ALL: Error : The length of result shape is 7.9487, expected 8.05281"
 
 puts "====================================="
 puts "OCC27341: Incorrect exact HLR results"
index 3e71edfe304d434613bf55bace15ca911ebf3941..d8cfc4688c102599eddfd159b63d6d23440c81e0 100644 (file)
@@ -1,3 +1,5 @@
+puts "TODO OCC30286 ALL: Error : The length of result shape is 8.40196, expected 8.39744"
+
 puts "====================================="
 puts "OCC27341: Incorrect exact HLR results"
 puts "====================================="
index 72303a8910c27e0a0d0fc56a87e4ed3eb0834578..980d50d0bfec92618c62d438466c03e5592266d1 100644 (file)
@@ -1,4 +1,4 @@
-puts "TODO OCC30286 ALL: Error : The length of result shape is 7.44464, expected 7.39488"
+puts "TODO OCC30286 ALL: Error : The length of result shape is 7.4452, expected 7.39488"
 
 puts "====================================="
 puts "OCC27341: Incorrect exact HLR results"
index f276fd4c4dccd07b06ccb1e30b032f134ceca0f1..3423f470fad4255e4e5a3af401f67350cd9231b5 100644 (file)
@@ -1,4 +1,4 @@
-puts "TODO OCC30286 ALL: Error : The length of result shape is 9.10542, expected 9.47163"
+puts "TODO OCC30286 ALL: Error : The length of result shape is 9.08401, expected 9.47163"
 
 puts "====================================="
 puts "OCC27341: Incorrect exact HLR results"
index f85f2d0066385fd678b4af1f822e41b8eec6f9cf..1f1e8a064160bfbfb8abc402aa3802034999e0a4 100644 (file)
@@ -1,3 +1,5 @@
+puts "TODO OCC30286 ALL: Error : The length of result shape is 7.64618, expected 7.64599"
+
 puts "====================================="
 puts "OCC27341: Incorrect exact HLR results"
 puts "====================================="
index dc38a1c33e886efdb500119ded181fe811673aaa..958ba5ba3961624df42b7cdc09b3bbbb49f19ae5 100644 (file)
@@ -1,3 +1,5 @@
+puts "TODO OCC30286 ALL: Error : The length of result shape is 9.30402, expected 9.30381"
+
 puts "====================================="
 puts "OCC27341: Incorrect exact HLR results"
 puts "====================================="