0028556: Invalid result of Fuse operation in the test case bugs moddata_2 bug469
authoremv <emv@opencascade.com>
Wed, 15 Mar 2017 06:15:46 +0000 (09:15 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 23 Mar 2017 12:57:24 +0000 (15:57 +0300)
1. Using appropriate intersection tolerance for splitting the degenerated edges in Boolean operations (void BOPAlgo_PaveFiller::FillPaves()).

2. Avoid creation of the wires consisting of degenerated edges only (BOPAlgo_WireSplitter).

3. Test case bugs/moddata_2/bug469 has been corrected to obtain valid result of operation. TODO statements have been removed from the case.

src/BOPAlgo/BOPAlgo_PaveFiller_8.cxx
src/BOPAlgo/BOPAlgo_WireSplitter_1.cxx
tests/bugs/moddata_2/bug469

index 308ceeb..eee930c 100644 (file)
@@ -231,7 +231,11 @@ void BOPAlgo_PaveFiller::ProcessDE()
 
 //=======================================================================
 //function : FillPaves
-//purpose  : 
+//purpose  : Find all pave blocks passing through the vertex <nVD> and
+//           intersecting the 2D curve of the degenerated edge
+//           somewhere in the middle. Save intersection points into
+//           Extra paves of the pave block of degenerated edge for future
+//           splitting.
 //=======================================================================
   void BOPAlgo_PaveFiller::FillPaves(const Standard_Integer nVD,
                                      const Standard_Integer nED,
@@ -239,102 +243,90 @@ void BOPAlgo_PaveFiller::ProcessDE()
                                      const BOPDS_ListOfPaveBlock& aLPBOut,
                                      const Handle(BOPDS_PaveBlock)& aPBD)
 {
-  Standard_Boolean bXDir, bIsDone;
-  Standard_Integer nE, aNbPoints, j, anInd;
-  Standard_Real aTD1, aTD2, aT1, aT2, aTolInter, aX, aDT;
-  Standard_Real aTolCmp;
-  gp_Pnt2d aP2d1, aP2d2, aP2D;
-  gp_Lin2d aLDE;
-  Handle(Geom2d_Line) aCLDE;
-  Handle(Geom2d_Curve) aC2DDE1, aC2D;
-  Handle(Geom2d_TrimmedCurve)aC2DDE;
-  BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
+  // Prepare pave to put to pave block as an Extra pave
   BOPDS_Pave aPave;
+  aPave.SetIndex(nVD);
   //
-  aDT=Precision::PConfusion();
+  const TopoDS_Vertex& aDV = (*(TopoDS_Vertex *)(&myDS->Shape(nVD)));
+  const TopoDS_Edge& aDE = (*(TopoDS_Edge *)(&myDS->Shape(nED)));
+  const TopoDS_Face& aDF = (*(TopoDS_Face *)(&myDS->Shape(nFD)));
   //
-  aPave.SetIndex(nVD);
+  Standard_Real aTolV = BRep_Tool::Tolerance(aDV);
+  const BRepAdaptor_Surface& aBAS = myContext->SurfaceAdaptor(aDF);
   //
-  const TopoDS_Edge& aDE=(*(TopoDS_Edge *)(&myDS->Shape(nED)));
-  const TopoDS_Face& aDF=(*(TopoDS_Face *)(&myDS->Shape(nFD)));
-  //aC2DDE
-  aC2DDE1=BRep_Tool::CurveOnSurface(aDE, aDF, aTD1, aTD2);
-  aC2DDE=new Geom2d_TrimmedCurve(aC2DDE1, aTD1, aTD2);
-  //aCLDE
-  Handle(Geom2d_TrimmedCurve) aCLDET1=Handle(Geom2d_TrimmedCurve)::DownCast(aC2DDE1);
-  if (aCLDET1.IsNull()) {
-    aCLDE=Handle(Geom2d_Line)::DownCast(aC2DDE1);
-  }
-  else {
-    Handle(Geom2d_Curve) aBasisCurve=aCLDET1->BasisCurve();
-    aCLDE=Handle(Geom2d_Line)::DownCast(aBasisCurve);
-  }
+  // 2D intersection tolerance should be computed as a resolution
+  // from the tolerance of vertex to resolve the touching cases
+  Standard_Real aTolInt = Precision::PConfusion();
+  // UResolution from the tolerance of the vertex
+  Standard_Real aURes = aBAS.UResolution(aTolV);
+  // VResolution from the tolerance of the vertex
+  Standard_Real aVRes = aBAS.VResolution(aTolV);
   //
-  // Choose direction for degenerated edge
-  aC2DDE->D0(aTD1, aP2d1);
-  aC2DDE->D0(aTD2, aP2d2);
+  aTolInt = Max(aTolInt, Max(aURes, aVRes));
   //
-  bXDir=Standard_False;
-  if (fabs(aP2d1.Y()-aP2d2.Y()) < aDT){
-    bXDir=!bXDir;
-  }
+  // Parametric tolerance to compare intersection point with boundaries
+  // should be computed as a resolution from the tolerance of vertex
+  // in the direction of the 2D curve of degenerated edge
+  Standard_Real aTolCmp = Precision::PConfusion();
+  // Get 2D curve
+  Standard_Real aTD1, aTD2;
+  Handle(Geom2d_Curve) aC2DDE = BRep_Tool::CurveOnSurface(aDE, aDF, aTD1, aTD2);
+  // Get direction of the curve
+  Standard_Boolean bUDir = Abs(aC2DDE->Value(aTD1).Y() - aC2DDE->Value(aTD2).Y()) < Precision::PConfusion();
+  //
+  aTolCmp = Max(aTolCmp, (bUDir ? aURes : aVRes));
   //
-  aItLPB.Initialize(aLPBOut);
+  // Prepare adaptor for the degenerated edge for intersection
+  Geom2dAdaptor_Curve aGAC1;
+  aGAC1.Load(aC2DDE, aTD1, aTD2);
+  //
+  BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPBOut);
   for (; aItLPB.More(); aItLPB.Next()) {
-    const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
-    nE=aPB->Edge();
+    const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
+    Standard_Integer nE = aPB->Edge();
     if (nE < 0) {
       continue;
     }
-    const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
-    aC2D=BRep_Tool::CurveOnSurface(aE, aDF, aT1, aT2);
+    const TopoDS_Edge& aE = (*(TopoDS_Edge *)(&myDS->Shape(nE)));
+    Standard_Real aT1, aT2;
+    Handle(Geom2d_Curve) aC2D = BRep_Tool::CurveOnSurface(aE, aDF, aT1, aT2);
     if (aC2D.IsNull()) {
       continue;
     }
     //
-    // Intersection
-    Geom2dAdaptor_Curve aGAC1, aGAC2;
-    aGAC1.Load(aC2DDE, aTD1, aTD2);
+    // Prepare adaptor for the passing edge for intersection
+    Geom2dAdaptor_Curve aGAC2;
     //
-    Handle(Geom2d_Line) aL2D= Handle(Geom2d_Line)::DownCast(aC2D);
+    Handle(Geom2d_Line) aL2D = Handle(Geom2d_Line)::DownCast(aC2D);
     if (!aL2D.IsNull()) {
       aGAC2.Load(aC2D);
     }
     else {
       aGAC2.Load(aC2D, aT1, aT2);
     }
-    //
-    aTolInter=0.001;
-    aTolCmp=1.414213562*aTolInter+aDT;
-    Geom2dInt_GInter aGInter(aGAC1, aGAC2, aTolInter, aTolInter);
-    bIsDone=aGInter.IsDone();
-    if(!bIsDone) {
-      continue;
-    }
-    //
-    aNbPoints=aGInter.NbPoints();
-    if (!aNbPoints){
+    // Intersection
+    Geom2dInt_GInter aGInter(aGAC1, aGAC2, aTolInt, aTolInt);
+    if (!aGInter.IsDone()) {
       continue;
     }
     //
-    for (j=1; j<=aNbPoints; ++j) {
-      aP2D=aGInter.Point(j).Value();
-      aX=aGInter.Point(j).ParamOnFirst();
-      //
-      if (fabs (aX-aTD1) < aTolCmp || fabs (aX-aTD2) < aTolCmp) {
-        continue; 
-      }
-      if (aX < aTD1 || aX > aTD2) {
-        continue; 
+    // Analyze intersection points
+    Standard_Integer i, aNbPoints = aGInter.NbPoints();
+    for (i = 1; i <= aNbPoints; ++i) {
+      Standard_Real aX = aGInter.Point(i).ParamOnFirst();
+      if (aX - aTD1 < aTolCmp || aTD2 - aX < aTolCmp) {
+        continue;
       }
       //
-      if (aPBD->ContainsParameter(aX, aDT, anInd)) {
+      Standard_Integer anInd;
+      if (aPBD->ContainsParameter(aX, aTolCmp, anInd)) {
         continue;
       }
+      //
       aPave.SetParameter(aX);
       aPBD->AppendExtPave1(aPave);
     }
-  }//for (; aItLPB.More(); aItLPB.Next()) {
+  }
 }
 //=======================================================================
 // function:  MakeSplitEdge1
index e1b1bdf..8ce0691 100644 (file)
@@ -42,6 +42,7 @@
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopLoc_Location.hxx>
+#include <TopoDS.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Iterator.hxx>
@@ -412,15 +413,23 @@ void Path (const GeomAdaptor_Surface& aGAS,
     bIsClosed = aVertMap.Find(aVb);
     {
       BOPCol_ListOfShape aBuf;
+      Standard_Boolean bHasEdge = Standard_False;
       //
       aNb = aLS.Length();
       for (i = aNb; i>0; --i) {
         const TopoDS_Shape& aVPrev=aVertVa(i);
         const gp_Pnt2d& aPaPrev=aCoordVa(i);
-        const TopoDS_Shape& aEPrev=aLS(i);
-        
+        const TopoDS_Edge& aEPrev = TopoDS::Edge(aLS(i));
+        //
         aBuf.Append(aEPrev);
-        
+        if (!bHasEdge) {
+          bHasEdge = !BRep_Tool::Degenerated(aEPrev);
+          // do not create wire from degenerated edges only
+          if (!bHasEdge) {
+            continue;
+          }
+        }
+        //
         anIsSameV = aVPrev.IsSame(aVb);
         anIsSameV2d = anIsSameV;
         if (anIsSameV) {
index f4bc4ba..bd61c13 100755 (executable)
@@ -1,8 +1,3 @@
-puts "TODO OCC28556 ALL: Faulty shapes in variables"
-puts "TODO OCC28556 ALL: The area of result shape is"
-puts "TODO OCC28556 ALL: The volume of result shape is"
-puts "TODO OCC28556 ALL: Error :  is WRONG because number of"
-
 puts "========================"
 puts " OCC469 "
 puts "========================"
@@ -12,10 +7,22 @@ puts ""
 ######################################################
 
 restore [locate_data_file OCC469.brep] a 
+# remove small edges from the shape
+fixsmalledges a a 0.002
+
+# explode to get two arguemnts
 explode a
 
+# use fuzzy value to treat misalignment of the arguments
+bfuzzyvalue 0.002
+
+# perform Boolean operation
 bfuse result a_1 a_2
 
+# restoring fuzzy value to zero
+bfuzzyvalue 0.0
+
+# check the obtained result
 checkshape result
 checkprops result -s 30523.3 -v 22730.1
 checknbshapes result -shell 1 -solid 1