]> OCCT Git - occt.git/commitdiff
0031890: Modeling Algorithms - Invalid result of common fuse BOP. Intersection has...
authorjgv <jgv@opencascade.com>
Sun, 6 Jun 2021 02:39:55 +0000 (05:39 +0300)
committerjfa <jfa@opencascade.com>
Mon, 30 Aug 2021 08:33:18 +0000 (11:33 +0300)
Modify the method BOPTools_AlgoTools3D::DoSplitSEAMOnFace: correct processing closed non-periodic surfaces.

src/BOPTools/BOPTools_AlgoTools3D.cxx
tests/bugs/modalg_7/bug31578 [new file with mode: 0644]
tests/bugs/modalg_7/bug31890 [new file with mode: 0644]

index 4de235a3919d0c5fca4ed0a6eb930ed10b782bb0..001da1875c2fe7ce29d1d572b180f6909a7cacfb 100644 (file)
@@ -77,7 +77,8 @@ Standard_Boolean BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSp
                                                           const TopoDS_Face& aF)
 {
   Standard_Boolean bIsUPeriodic, bIsVPeriodic, bIsLeft;
-  Standard_Real aTol, a, b, anUPeriod, anVPeriod, aT, anU, dU, anU1;
+  Standard_Real anUPeriod = 0., anVPeriod = 0.;
+  Standard_Real aTol, a, b, aT, anU, dU, anU1;
   Standard_Real aScPr, anV, dV, anV1;
   Standard_Real aUmin, aUmax, aVmin, aVmax;
   gp_Pnt2d aP2D;
@@ -98,58 +99,64 @@ Standard_Boolean BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSp
   //
   aS->Bounds(aUmin, aUmax, aVmin, aVmax);
   //
-  bIsUPeriodic=aS->IsUPeriodic();
-  bIsVPeriodic=aS->IsVPeriodic();
-  //
-  anUPeriod = bIsUPeriodic ? aS->UPeriod() : 0.;
-  anVPeriod = bIsVPeriodic ? aS->VPeriod() : 0.;
+
+  bIsUPeriodic = aS->IsUClosed();
+  bIsVPeriodic = aS->IsVClosed();
+
+  if (bIsUPeriodic)
+    anUPeriod = aUmax - aUmin;
+  if (bIsVPeriodic)
+    anVPeriod = aVmax - aVmin;
+  
   //
   if (!bIsUPeriodic && !bIsVPeriodic) {
-    Standard_Boolean bIsUClosed, bIsVClosed;
-    Handle(Geom_BSplineSurface) aBS;
-    Handle(Geom_BezierSurface) aBZ;
+    
     Handle(Geom_RectangularTrimmedSurface) aRTS;
+    aRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
     //
-    bIsUClosed=Standard_False;
-    bIsVClosed=Standard_False;
-    aBS=Handle(Geom_BSplineSurface)::DownCast(aS);
-    aBZ=Handle(Geom_BezierSurface) ::DownCast(aS);
-    aRTS=Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
-    //
-    if (!aBS.IsNull()) {
-      bIsUClosed=aBS->IsUClosed();
-      bIsVClosed=aBS->IsVClosed();
-    }
-    else if (!aBZ.IsNull()) {
-      bIsUClosed=aBZ->IsUClosed();
-      bIsVClosed=aBZ->IsVClosed();
-    }
-    else if (!aRTS.IsNull()) {
+    if (aRTS.IsNull())
+      return Standard_False;
+    
+    else {
       Handle(Geom_Surface) aSB;
       //
-      aSB=aRTS->BasisSurface();
-      bIsUPeriodic=aSB->IsUPeriodic();
-      bIsVPeriodic=aSB->IsVPeriodic();
+      aSB = aRTS->BasisSurface();
+      bIsUPeriodic = aSB->IsUPeriodic();
+      bIsVPeriodic = aSB->IsVPeriodic();
       //
-      if (!(bIsUPeriodic || bIsVPeriodic)) {
-        return Standard_False;
-      }
-      anUPeriod = bIsUPeriodic ? aSB->UPeriod() : 0.;
-      anVPeriod = bIsVPeriodic ? aSB->VPeriod() : 0.;
-    }
-    //
-    if (aRTS.IsNull()) {
-      if (!bIsUClosed && !bIsVClosed) {
-        return Standard_False;
+
+      if (bIsUPeriodic || bIsVPeriodic)
+      {
+        anUPeriod = bIsUPeriodic ? aSB->UPeriod() : 0.;
+        anVPeriod = bIsVPeriodic ? aSB->VPeriod() : 0.;
       }
-      //
-      if (bIsUClosed) {
-        anUPeriod=aUmax-aUmin;
+      else
+      {
+        Standard_Boolean bIsUClosed = aSB->IsUClosed();
+        Standard_Boolean bIsVClosed = aSB->IsVClosed();
+        Standard_Real aGlobalUmin, aGlobalUmax, aGlobalVmin, aGlobalVmax;
+        aSB->Bounds(aGlobalUmin, aGlobalUmax, aGlobalVmin, aGlobalVmax);
+
+        if (bIsUClosed &&
+            Abs(aUmin - aGlobalUmin) < aTol &&
+            Abs(aUmax - aGlobalUmax) < aTol)
+        {
+          bIsUPeriodic = Standard_True;
+          anUPeriod = aUmax - aUmin;
+        }
+        if (bIsVClosed &&
+            Abs(aVmin - aGlobalVmin) < aTol &&
+            Abs(aVmax - aGlobalVmax) < aTol)
+        {
+          bIsVPeriodic = Standard_True;
+          anVPeriod = aVmax - aVmin;
+        }
       }
-      if (bIsVClosed) {
-        anVPeriod=aVmax-aVmin;
+      
+      if (!(bIsUPeriodic || bIsVPeriodic)) {
+        return Standard_False;
       }
-    }
+    } //if !RTS.IsNull
   }
   //
   //---------------------------------------------------
diff --git a/tests/bugs/modalg_7/bug31578 b/tests/bugs/modalg_7/bug31578
new file mode 100644 (file)
index 0000000..752aa44
--- /dev/null
@@ -0,0 +1,31 @@
+puts "========================================"
+puts "0031578: BOP: wrong result in Debug mode"
+puts "========================================"
+puts ""
+
+restore [locate_data_file bug31578_a.brep] a
+restore [locate_data_file bug31578_b.brep] b
+
+bclearobjects
+bcleartools
+baddobjects a
+baddtools   b
+
+bfillds
+
+bbuild r
+checkshape r
+
+set tolres [checkmaxtol r]
+
+if { ${tolres} > 7.e-7} {
+   puts "Error: bad tolerance of result"
+}
+
+checknbshapes r -solid 3 -shell 3 -face 21 -wire 21 -edge 36 -vertex 19
+
+bbop r_1 1
+
+checkshape r_1
+checknbshapes r_1 -solid 1 -shell 1 -face 18 -wire 18
+checkprops r_1 -s 0.035795 -v 6.60461e-05
diff --git a/tests/bugs/modalg_7/bug31890 b/tests/bugs/modalg_7/bug31890
new file mode 100644 (file)
index 0000000..f6d37c0
--- /dev/null
@@ -0,0 +1,36 @@
+puts "TODO CR29596 ALL: Warning: Intersection of pair of shapes has failed"
+
+puts "=========================================="
+puts "0031890: Invalid result of common fuse BOP"
+puts "=========================================="
+puts ""
+
+restore [locate_data_file bug31890_sol.brep] sol
+restore [locate_data_file bug31890_ext.brep] ext
+
+bclearobjects
+bcleartools
+baddobjects sol
+baddtools ext
+
+bfillds
+
+bbuild inv
+checkshape inv
+
+set tolres [checkmaxtol inv]
+
+if { ${tolres} > 6.e-6} {
+   puts "Error: bad tolerance of result"
+}
+
+bbop r_0 0
+bbop r_1 1
+
+checkshape r_0
+checknbshapes r_0 -solid 1 -shell 1 -face 9 -wire 11
+checkprops r_0 -s 58.2381 -v 14.1288
+
+checkshape r_1
+checknbshapes r_1 -solid 1 -shell 1 -face 16 -wire 18
+checkprops r_1 -s 91.6213 -v 39.4973