diff --git a/src/BOPTools/BOPTools_AlgoTools.cxx b/src/BOPTools/BOPTools_AlgoTools.cxx index 58cbb7cfbd..ce6f0c600b 100644 --- a/src/BOPTools/BOPTools_AlgoTools.cxx +++ b/src/BOPTools/BOPTools_AlgoTools.cxx @@ -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; } //======================================================================= diff --git a/src/BOPTools/BOPTools_AlgoTools.hxx b/src/BOPTools/BOPTools_AlgoTools.hxx index bb12821fe7..18576d0522 100644 --- a/src/BOPTools/BOPTools_AlgoTools.hxx +++ b/src/BOPTools/BOPTools_AlgoTools.hxx @@ -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 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 diff --git a/tests/bugs/modalg_7/bug27928 b/tests/bugs/modalg_7/bug27928 index 5399984849..d48df7980e 100644 --- a/tests/bugs/modalg_7/bug27928 +++ b/tests/bugs/modalg_7/bug27928 @@ -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 -set bug_info [string trim [explode r]] -if {$bug_info == ""} { - puts "ERROR: OCC27928 is reproduced. Result of bcommon is empty." +bbop r0 0 +bbop r1 1 +bbop r2 2 +bbop r3 3 +bbop r4 4 + +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