1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-05 18:16:23 +03:00

0027928: BOP common produces empty compound

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.
This commit is contained in:
emv 2018-08-29 09:08:13 +03:00 committed by bugmaster
parent 7eb3580b79
commit 56062e13f2
3 changed files with 73 additions and 46 deletions

View 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)
{
aState = BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
theContext);
// Hatcher fails to find the point -> get point near some edge
aExp.Init(theF, TopAbs_EDGE);
for (; aExp.More() && iErr != 0; aExp.Next())
{
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;
}
//=======================================================================

View 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

View 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
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