0027928: BOP common produces empty compound
authoremv <emv@opencascade.com>
Wed, 29 Aug 2018 06:08:13 +0000 (09:08 +0300)
committerbugmaster <bugmaster@opencascade.com>
Sat, 1 Sep 2018 08:07:05 +0000 (11:07 +0300)
BOPTools_AlgoTools::ComputeState - increase the chance of correct classification of the face relatively solid by classifying the point located inside that face instead of the point taken near the edge of that face.
Test case for the issue.

src/BOPTools/BOPTools_AlgoTools.cxx
src/BOPTools/BOPTools_AlgoTools.hxx
tests/bugs/modalg_7/bug27928

index 58cbb7c..ce6f0c6 100644 (file)
@@ -617,46 +617,50 @@ TopAbs_State BOPTools_AlgoTools::ComputeState
   (const TopoDS_Face& theF,
    const TopoDS_Solid& theRef,
    const Standard_Real theTol,
-   TopTools_IndexedMapOfShape& theBounds,
+   const TopTools_IndexedMapOfShape& theBounds,
    const Handle(IntTools_Context)& theContext)
 {
-  TopAbs_State aState;
-  TopExp_Explorer aExp; 
-  TopoDS_Edge aE1;
-  gp_Pnt2d aP2D;
-  gp_Pnt aP3D; 
-  //
-  aState=TopAbs_UNKNOWN;
-  //
-  aExp.Init(theF, TopAbs_EDGE);
-  for (; aExp.More(); aExp.Next()) {
-    const TopoDS_Edge& aSE=(*(TopoDS_Edge*)(&aExp.Current()));
-    if (BRep_Tool::Degenerated(aSE)) {
+  TopAbs_State aState = TopAbs_UNKNOWN;
+
+  // Try to find the edge on the face which does not
+  // belong to the solid and classify the middle point of that
+  // edge relatively solid.
+  TopExp_Explorer aExp(theF, TopAbs_EDGE);
+  for (; aExp.More(); aExp.Next())
+  {
+    const TopoDS_Edge& aSE = (*(TopoDS_Edge*)(&aExp.Current()));
+    if (BRep_Tool::Degenerated(aSE))
       continue;
-    }
-    //
-    if (!theBounds.Contains(aSE)) {
-      const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aSE));
-      aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol, 
-                                              theContext);
+
+    if (!theBounds.Contains(aSE))
+    {
+      aState = BOPTools_AlgoTools::ComputeState(aSE, theRef, theTol, theContext);
       return aState;
     }
-    if (aE1.IsNull()) {
-      aE1=(*(TopoDS_Edge*)(&aSE));
-    }
   }
-  // !!<- process edges that are all on theRef
-  if (!aE1.IsNull()) {
-    const Standard_Integer anErrID = BOPTools_AlgoTools3D::PointNearEdge(aE1, theF,
-                                                                         aP2D, aP3D,
-                                                                         theContext);
-    if(anErrID == 0)
+
+  // All edges of the face are on the solid.
+  // Get point inside the face and classify it relatively solid.
+  gp_Pnt aP3D;
+  gp_Pnt2d aP2D;
+  Standard_Integer iErr = BOPTools_AlgoTools3D::PointInFace(theF, aP3D, aP2D, theContext);
+  if (iErr != 0)
+  {
+    // Hatcher fails to find the point -> get point near some edge
+    aExp.Init(theF, TopAbs_EDGE);
+    for (; aExp.More() && iErr != 0; aExp.Next())
     {
-      aState = BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
-                                                theContext);
+      const TopoDS_Edge& aSE = TopoDS::Edge(aExp.Current());
+      if (BRep_Tool::Degenerated(aSE))
+        continue;
+
+      iErr = BOPTools_AlgoTools3D::PointNearEdge(aSE, theF, aP2D, aP3D, theContext);
     }
   }
-  //
+
+  if (iErr == 0)
+    aState = BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, theContext);
+
   return aState;
 }
 //=======================================================================
index bb12821..18576d0 100644 (file)
@@ -202,13 +202,13 @@ public: //! @name Point/Edge/Face classification relatively solid
   //! Computes the 3-D state of the face theFace
   //! toward solid theSolid.
   //! theTol - value of precision of computation
-  //! theBounds - set of edges of theFace to avoid
+  //! theBounds - set of edges of <theSolid> to avoid
   //! theContext- cahed geometrical tools
   //! Returns 3-D state.
   Standard_EXPORT static TopAbs_State ComputeState(const TopoDS_Face& theFace,
                                                    const TopoDS_Solid& theSolid,
                                                    const Standard_Real theTol,
-                                                   TopTools_IndexedMapOfShape& theBounds,
+                                                   const TopTools_IndexedMapOfShape& theBounds,
                                                    const Handle(IntTools_Context)& theContext);
   
   //! Computes the 3-D state of the shape theShape
index 5399984..d48df79 100644 (file)
@@ -1,19 +1,42 @@
-puts "TODO OCC27928 ALL: ERROR: OCC27928 is reproduced."
-
-puts "========"
-puts "OCC27928"
-puts "========"
-puts ""
-######################################
-# BOP common produces empty compound
-######################################
+puts "=============================================================="
+puts "OCC27928: BOP common produces empty compound"
+puts "=============================================================="
 
 restore [locate_data_file bug27928_b1.brep] b1
 restore [locate_data_file bug27928_b2.brep] b2
 
-bcommon result b1 b2
+bclearobjects
+bcleartools
+baddobjects b1
+baddtools b2
+bfillds
+
+bbop r0 0
+bbop r1 1
+bbop r2 2
+bbop r3 3
+bbop r4 4
 
-set bug_info [string trim [explode r]]
-if {$bug_info == ""} {
-  puts "ERROR: OCC27928 is reproduced. Result of bcommon is empty."
+foreach r {r0 r1 r2 r3 r4} {
+  checkshape $r
+  if {![regexp "OK" [bopcheck $r]]} {
+    puts "Error: the result of BOP is self-interfering shape"
+  }
 }
+
+checknbshapes r0 -wire 8 -face 8 -shell 1 -solid 1
+checkprops r0 -s 21820.6 -v 221499
+
+checknbshapes r1 -wire 14 -face 14 -shell 1 -solid 1
+checkprops r1 -s 22455.1 -v 224813
+
+checknbshapes r2 -wire 5 -face 5 -shell 1 -solid 1
+checkprops r2 -s 2075.44 -v 1489.33
+
+checknbshapes r3 -wire 5 -face 5 -shell 1 -solid 1
+checkprops r3 -s 2521.83 -v 1824.69
+
+checknbshapes r4 -vertex 12 -edge 18 -t
+checkprops r4 -l 825.645
+
+checkview -display r0 -2d -path ${imagedir}/${test_image}.png