0023876: New Boolean Operation algorithm works incorrect with cylinder made by revolu...
authoromy <omy@opencascade.com>
Fri, 12 Apr 2013 09:26:04 +0000 (13:26 +0400)
committeromy <omy@opencascade.com>
Fri, 12 Apr 2013 09:26:04 +0000 (13:26 +0400)
Added treatment for surfaces periodic in the V parametric direction.
Added test case bugs modalg_5/bug23876

src/BOPTools/BOPTools_AlgoTools3D.cxx
tests/bugs/modalg_2/bug5805_41
tests/bugs/modalg_5/bug23876 [new file with mode: 0644]

index a8411d5..ceccc15 100644 (file)
@@ -88,10 +88,11 @@ static
 //purpose  : 
 //=======================================================================
   void BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSplit,
-                                            const TopoDS_Face& aF)
+                                                const TopoDS_Face& aF)
 {
-  Standard_Boolean bIsUPeriodic, bIsLeft;
-  Standard_Real aTol, a, b, anUPeriod, aT, anU, dU=1.e-7, anU1;
+  Standard_Boolean bIsUPeriodic, bIsVPeriodic, bIsLeft;
+  Standard_Real aTol, a, b, anUPeriod, anVPeriod, aT, anU, dU=1.e-7, anU1,
+                anV, dV=1.e-7, anV1;
   Standard_Real aScPr;
   gp_Pnt2d aP2D;
   gp_Vec2d aVec2D;
@@ -104,73 +105,94 @@ static
   //
   aSp=aSplit;
   aSp.Orientation(TopAbs_FORWARD);
-  
   aTol=BRep_Tool::Tolerance(aSp);
-
+  //
   aS=BRep_Tool::Surface(aF);
   bIsUPeriodic=aS->IsUPeriodic();
-  
-  anUPeriod=0.;
-  if (bIsUPeriodic) {
-    anUPeriod=aS->UPeriod();
-  }
-  else {
-    Standard_Boolean bIsUClosed;
+  bIsVPeriodic=aS->IsVPeriodic();
+  //
+  anUPeriod = bIsUPeriodic ? aS->UPeriod() : 0.;
+  anVPeriod = bIsVPeriodic ? aS->VPeriod() : 0.;
+  //
+  if (!bIsUPeriodic && !bIsVPeriodic) {
+    Standard_Boolean bIsUClosed, bIsVClosed;
     Standard_Real aUmin, aUmax, aVmin, aVmax;
     Handle(Geom_BSplineSurface) aBS;
     Handle(Geom_BezierSurface) aBZ;
     //
     bIsUClosed=Standard_False;
+    bIsVClosed=Standard_False;
     aBS=Handle(Geom_BSplineSurface)::DownCast(aS);
     aBZ=Handle(Geom_BezierSurface) ::DownCast(aS);
     //
     if (!aBS.IsNull()) {
       bIsUClosed=aBS->IsUClosed();
+      bIsVClosed=aBS->IsVClosed();
       aBS->Bounds(aUmin, aUmax, aVmin, aVmax);
     }
     else if (!aBZ.IsNull()) {
       bIsUClosed=aBZ->IsUClosed();
+      bIsVClosed=aBZ->IsVClosed();
       aBZ->Bounds(aUmin, aUmax, aVmin, aVmax);
     }
-    if (!bIsUClosed) {
+    if (!bIsUClosed && !bIsVClosed) {
       return;
     }
     //
-    anUPeriod=aUmax-aUmin;
+    if (bIsUClosed) {
+      anUPeriod=aUmax-aUmin;
+    }
+    if (bIsVClosed) {
+      anVPeriod=aVmax-aVmin;
+    }
   }
   //
   C2D1=BRep_Tool::CurveOnSurface(aSp, aF, a, b);
   //
   aT=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
   C2D1->D1(aT, aP2D, aVec2D);
-  gp_Dir2d aDir2D1(aVec2D);
-  
+  gp_Dir2d aDir2D1(aVec2D), aDOX(-1.,0.), aDOY(0.,1.);
   //
-  gp_Dir2d aDOY(0.,1.);
-  aScPr=aDir2D1*aDOY;
+  anU=aP2D.X();
+  anV=aP2D.Y();
   //
+  anU1=anU;
+  anV1=anV;
   //
-  anU=aP2D.X();
-  if (fabs (anU) < dU) {
-    bIsLeft=Standard_True;
-    anU1=anU+anUPeriod;
+  if (anUPeriod > 0.){
+    if (fabs (anU) < dU) {
+      bIsLeft=Standard_True;
+      anU1=anU+anUPeriod;
+    }
+    else if (fabs (anU-anUPeriod) < dU) {
+      bIsLeft=Standard_False;
+      anU1=anU-anUPeriod;
+    }
   }
-  else if (fabs (anU-anUPeriod) < dU) {
-    bIsLeft=Standard_False;
-    anU1=anU-anUPeriod;
+  //
+  if (anVPeriod > 0.) {
+    if (fabs (anV) < dV) {
+      bIsLeft=Standard_True;
+      anV1=anV+anVPeriod;
+    }
+    else if (fabs (anV-anVPeriod) < dV) {
+      bIsLeft=Standard_False;
+      anV1=anV-anVPeriod;
+    }
   }
-  else {
+  //
+  if (anU1==anU && anV1==anV) {
     return;
   }
   //
-  
-  
+  aScPr = (anU1==anU) ? aDir2D1*aDOX : aDir2D1*aDOY;
+  //
   aTmpC1=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
   Handle(Geom2d_TrimmedCurve) aC1 = new Geom2d_TrimmedCurve(aTmpC1, a, b);
-
+  //
   aTmpC2=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
   Handle(Geom2d_TrimmedCurve) aC2 = new Geom2d_TrimmedCurve(aTmpC2, a, b);
-  gp_Vec2d aTrV(anU1-anU, 0.);
+  gp_Vec2d aTrV(anU1-anU, anV1-anV);
   aC2->Translate(aTrV);
   //
   if (!bIsLeft) {
@@ -189,7 +211,6 @@ static
       BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
     }
   }
-  //
 }
 
 //=======================================================================
index 94fdf3b..1cbb414 100755 (executable)
@@ -1,6 +1,6 @@
 puts "TODO OCC11111 ALL: Error : Result shape is WRONG"
 puts "TODO OCC11111 ALL: Error : The square of result shape is"
-puts "TODO OCC11111 ALL: Faulty shapes in variables faulty_1 to faulty_"
+puts "TODO ?OCC11111 ALL: Faulty shapes in variables faulty_1 to faulty_"
 puts "TODO ?OCC11111 ALL: Faulty OCC5805 : result is not Closed shape"
 puts "TODO ?OCC11111 ALL: Error : The command is not valid"
 puts "============"
diff --git a/tests/bugs/modalg_5/bug23876 b/tests/bugs/modalg_5/bug23876
new file mode 100644 (file)
index 0000000..af5ff11
--- /dev/null
@@ -0,0 +1,29 @@
+puts "============"
+puts "OCC23876"
+puts "============"
+puts ""
+###############################################################################################
+# New Boolean Operation algorithm works incorrect with cylinder made by revolution and torus
+###############################################################################################
+
+vertex v1 10 0 0
+vertex v2 20 0 0
+vertex v3 10 0 50
+vertex v4 20 0 50
+edge e1 v1 v3
+edge e2 v3 v4
+edge e3 v2 v4
+edge e4 v2 v1
+wire w e1 e2 e3 e4
+mkplane f w
+revol b1 f 0 0 0 0 0 1 360
+don b1
+ptorus b2 15 5
+ttranslate b2 0 0 50
+
+bop b1 b2
+bopcommon result
+
+set square 2422.92
+set 2dviewer 0
+