1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-07 18:30:55 +03:00

0029646: Boolean Operations algorithm produces a face with self-intersecting wire

Boolean operations - Allow repeated intersection of edges to find the coinciding pairs.
Previously, only the edges rejected by bounding boxes classification has been additionally checked on coincidence. The current patch removes this filter allowing all edges with coinciding vertices to be checked on coincidence.

Adjustment of the test cases for current behavior:
1. The following cases are improvements:
boolean volumemaker A8
bugs modalg_1 buc60703_1
bugs modalg_1 buc60703_2
bugs modalg_1 buc60703_4
bugs modalg_6 bug26789_1
bugs modalg_6 bug26789_2
bugs modalg_7 bug26883_4
bugs modalg_7 bug27948

2. bugs modalg_7 bug29580_1 is modified to extend the validity checks.
This commit is contained in:
emv 2018-03-26 15:06:18 +03:00 committed by bugmaster
parent 4563472c1e
commit f816395691
11 changed files with 112 additions and 150 deletions

View File

@ -708,45 +708,53 @@ void MakeInternalWires(const TopTools_IndexedMapOfShape& theME,
//function : IsInside //function : IsInside
//purpose : //purpose :
//======================================================================= //=======================================================================
Standard_Boolean IsInside(const TopoDS_Shape& theHole, Standard_Boolean IsInside(const TopoDS_Shape& theWire,
const TopoDS_Shape& theF2, const TopoDS_Shape& theF,
Handle(IntTools_Context)& theContext) Handle(IntTools_Context)& theContext)
{ {
Standard_Boolean bRet; // Check if the wire is located inside the face:
Standard_Real aT, aU, aV; // take unique point from the wire and classify it relatively the face
TopAbs_State aState;
TopExp_Explorer aExp;
TopTools_IndexedMapOfShape aME2;
gp_Pnt2d aP2D;
//
bRet=Standard_False;
aState=TopAbs_UNKNOWN;
const TopoDS_Face& aF2=(*(TopoDS_Face *)(&theF2));
//
TopExp::MapShapes(aF2, TopAbs_EDGE, aME2);//AA
//
aExp.Init(theHole, TopAbs_EDGE);
if (aExp.More()) {
const TopoDS_Edge& aE =(*(TopoDS_Edge *)(&aExp.Current()));
if (aME2.Contains(aE)) {
return bRet;
}
if (!BRep_Tool::Degenerated(aE)) {
//
aT=BOPTools_AlgoTools2D::IntermediatePoint(aE);
BOPTools_AlgoTools2D::PointOnSurface(aE, aF2, aT, aU, aV, theContext);
aP2D.SetCoord(aU, aV);
//
IntTools_FClass2d& aClsf=theContext->FClass2d(aF2);
aState=aClsf.Perform(aP2D);
bRet=(aState==TopAbs_IN);
}
}
//
return bRet;
}
// Avoid edges of the face
TopTools_IndexedMapOfShape aFaceEdgesMap;
TopExp::MapShapes(theF, TopAbs_EDGE, aFaceEdgesMap);
// Get classification tool from the context
const TopoDS_Face& aF = TopoDS::Face(theF);
IntTools_FClass2d& aClassifier = theContext->FClass2d(aF);
Standard_Boolean isInside = Standard_False;
// Iterate on wire edges until first classification is performed
TopExp_Explorer anExp(theWire, TopAbs_EDGE);
for (; anExp.More(); anExp.Next())
{
const TopoDS_Edge& aE = TopoDS::Edge(anExp.Current());
if (BRep_Tool::Degenerated(aE))
// Avoid checking degenerated edges.
continue;
if (aFaceEdgesMap.Contains(aE))
// Face contains the edge from the wire, thus the wire cannot be
// inside that face.
return isInside;
// Get 2d curve of the edge on the face
Standard_Real aT1, aT2;
const Handle(Geom2d_Curve)& aC2D = BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
if (aC2D.IsNull())
continue;
// Get middle point on the curve
gp_Pnt2d aP2D = aC2D->Value((aT1 + aT2) / 2.);
// Classify the point
TopAbs_State aState = aClassifier.Perform(aP2D);
isInside = (aState == TopAbs_IN);
break;
}
return isInside;
}
//======================================================================= //=======================================================================
//function : IsGrowthWire //function : IsGrowthWire
//purpose : //purpose :

View File

@ -803,8 +803,8 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator; Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
// Initialize pave blocks for all SD vertices // Initialize pave blocks for all SD vertices
Standard_Integer i, aNbS = myDS->NbSourceShapes(); const Standard_Integer aNbS = myDS->NbSourceShapes();
for (i = 0; i < aNbS; ++i) for (Standard_Integer i = 0; i < aNbS; ++i)
{ {
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
if (aSI.ShapeType() == TopAbs_VERTEX) if (aSI.ShapeType() == TopAbs_VERTEX)
@ -822,11 +822,22 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
// Fence map of pave blocks // Fence map of pave blocks
BOPDS_MapOfPaveBlock aMPBFence(1, anAlloc); BOPDS_MapOfPaveBlock aMPBFence(1, anAlloc);
BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool(); for (Standard_Integer i = 0; i < aNbS; ++i)
Standard_Integer aNbPBP = aPBP.Length();
for (i = 0; i < aNbPBP; ++i)
{ {
BOPDS_ListOfPaveBlock& aLPB = aPBP(i); const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
if (aSI.ShapeType() != TopAbs_EDGE)
// Not an edge
continue;
if (!aSI.HasReference())
// Edge has no pave blocks
continue;
if (aSI.HasFlag())
// Degenerated edge
continue;
const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks(i);
BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB); BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
for (; aItLPB.More(); aItLPB.Next()) for (; aItLPB.More(); aItLPB.Next())
{ {
@ -852,23 +863,11 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
if (!aNbPB) if (!aNbPB)
return; return;
// Find pairs of Pave Blocks having the same SD vertices, // Find pairs of Pave Blocks having the same SD vertices
// rejecting the pairs of edges that have already been intersected // and put them into the vector for parallel intersection.
// Prepare map of pairs of intersected edges
BOPDS_MapOfPair aMEEDone(1, anAlloc);
myIterator->Initialize(TopAbs_EDGE, TopAbs_EDGE);
for (; myIterator->More(); myIterator->Next())
{
Standard_Integer nE1, nE2;
myIterator->Value(nE1, nE2);
aMEEDone.Add(BOPDS_Pair(nE1, nE2));
}
// Vector of pairs for intersection
BOPAlgo_VectorOfEdgeEdge aVEdgeEdge; BOPAlgo_VectorOfEdgeEdge aVEdgeEdge;
for (i = 1; i <= aNbPB; ++i) for (Standard_Integer i = 1; i <= aNbPB; ++i)
{ {
const BOPDS_ListOfPaveBlock& aLPB = aPBMap(i); const BOPDS_ListOfPaveBlock& aLPB = aPBMap(i);
if (aLPB.Extent() < 2) if (aLPB.Extent() < 2)
@ -891,6 +890,7 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
for (; aItLPB1.More(); aItLPB1.Next()) for (; aItLPB1.More(); aItLPB1.Next())
{ {
const Handle(BOPDS_PaveBlock)& aPB1 = aItLPB1.Value(); const Handle(BOPDS_PaveBlock)& aPB1 = aItLPB1.Value();
const Handle(BOPDS_CommonBlock)& aCB1 = myDS->CommonBlock(aPB1);
const Standard_Integer nE1 = aPB1->OriginalEdge(); const Standard_Integer nE1 = aPB1->OriginalEdge();
const TopoDS_Edge& aE1 = TopoDS::Edge(myDS->Shape(nE1)); const TopoDS_Edge& aE1 = TopoDS::Edge(myDS->Shape(nE1));
Standard_Real aT11, aT12; Standard_Real aT11, aT12;
@ -900,15 +900,20 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
for (aItLPB2.Next(); aItLPB2.More(); aItLPB2.Next()) for (aItLPB2.Next(); aItLPB2.More(); aItLPB2.Next())
{ {
const Handle(BOPDS_PaveBlock)& aPB2 = aItLPB2.Value(); const Handle(BOPDS_PaveBlock)& aPB2 = aItLPB2.Value();
const Handle(BOPDS_CommonBlock)& aCB2 = myDS->CommonBlock(aPB2);
const Standard_Integer nE2 = aPB2->OriginalEdge(); const Standard_Integer nE2 = aPB2->OriginalEdge();
if (aMEEDone.Contains(BOPDS_Pair(nE1, nE2)))
continue;
// Make sure that the edges came from different arguments // Make sure that the edges came from different arguments
if (myDS->Rank(nE1) == myDS->Rank(nE2)) if (myDS->Rank(nE1) == myDS->Rank(nE2))
continue; continue;
// Check that the Pave blocks do not form the Common block already
if (!aCB1.IsNull() && !aCB2.IsNull())
{
if (aCB1 == aCB2)
continue;
}
const TopoDS_Edge& aE2 = TopoDS::Edge(myDS->Shape(nE2)); const TopoDS_Edge& aE2 = TopoDS::Edge(myDS->Shape(nE2));
Standard_Real aT21, aT22; Standard_Real aT21, aT22;
aPB2->Range(aT21, aT22); aPB2->Range(aT21, aT22);
@ -932,7 +937,6 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
aPBMap.Clear(); aPBMap.Clear();
aMPBFence.Clear(); aMPBFence.Clear();
aMEEDone.Clear();
anAlloc->Reset(); anAlloc->Reset();
// Perform intersection of the found pairs // Perform intersection of the found pairs
@ -947,7 +951,7 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock aMPBLPB(1, anAlloc); BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock aMPBLPB(1, anAlloc);
for (i = 0; i < aNbPairs; ++i) for (Standard_Integer i = 0; i < aNbPairs; ++i)
{ {
BOPAlgo_EdgeEdge& anEdgeEdge = aVEdgeEdge(i); BOPAlgo_EdgeEdge& anEdgeEdge = aVEdgeEdge(i);
if (!anEdgeEdge.IsDone() || anEdgeEdge.HasErrors()) if (!anEdgeEdge.IsDone() || anEdgeEdge.HasErrors())

View File

@ -1,8 +1,5 @@
# test script on make volume operation # test script on make volume operation
# plane sphere # plane sphere
puts "TODO OCC26020 ALL: Faulty shapes in variables faulty_1 to faulty_"
puts "TODO OCC26020 ALL: Error: bopcheck failed"
puts "TODO OCC26020 ALL: Error : The area of result shape is"
# planar face # planar face
plane pln_f1 -4.2580937183769834 -506.18339008981781 147.62942729477928 0.98768834059988952 -6.6728564553435301e-012 -0.15643446501022945 plane pln_f1 -4.2580937183769834 -506.18339008981781 147.62942729477928 0.98768834059988952 -6.6728564553435301e-012 -0.15643446501022945
@ -42,5 +39,5 @@ mkface f7 sph_f7
# make volume operation # make volume operation
mkvolume result f1 f2 f3 f4 f5 f6 f7 mkvolume result f1 f2 f3 f4 f5 f6 f7
checkprops result -s 2.19944e+013 checkprops result -s 1.75676e+007
checknbshapes result -wire 68 -face 68 -shell 24 -solid 24

View File

@ -1,7 +1,3 @@
#puts "TODO OCC12345 ALL: An exception was caught"
#puts "TODO OCC12345 ALL: \\*\\* Exception"
#puts "TODO OCC12345 ALL: Faulty BUC60703: here is problem with FUSE operation"
puts "========================" puts "========================"
puts "BUC60703" puts "BUC60703"
puts "=================================" puts "================================="
@ -21,17 +17,10 @@ restore [locate_data_file buc60703b.brep] b
# maxtolerance b # maxtolerance b
checkshape b checkshape b
if [catch {bfuse result a b } catch_result] { bfuse result a b
puts "Faulty BUC60703: here is problem with FUSE operation"
} else {
puts "OK OCC348: function FUSE works ok"
if [catch {checkshape result } catch_result] {
puts "Faulty BUC60703 : here is checking problem."
} else {
puts "BUC60703 OK"
}
# maxtolerance res
checkprops result -s 237.333
checkview -display result -2d -path ${imagedir}/${test_image}.png
}
checkshape result
checkprops result -s 173.109 -v 129.814
checknbshapes result -wire 10 -face 10 -shell 1 -solid 1
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -1,4 +1,3 @@
puts "========================" puts "========================"
puts "BUC60703" puts "BUC60703"
puts "=================================" puts "================================="
@ -10,22 +9,12 @@ puts ""
############################################ ############################################
restore [locate_data_file buc60703c.brep] a restore [locate_data_file buc60703c.brep] a
checkshape a
restore [locate_data_file buc60703e.brep] b restore [locate_data_file buc60703e.brep] b
checkshape b
bfuse result a b
checkshape result
checkprops result -s 172.662 -v 129.604
checknbshapes result -wire 10 -face 10 -shell 1 -solid 1
if [catch {bfuse result a b } catch_result] {
puts "Faulty BUC60703: here is problem with FUSE operation"
} else {
puts "OK BUC60703: function FUSE works ok"
if [catch {checkshape result } catch_result] {
puts "WARNING BUC60703 : Function checkshape gives bad result"
puts " See also OCC438: 919 D3 and D4"
} else {
puts "BUC60703 OK in checkshape"
}
}
checkprops result -s 236.72
checkview -display result -2d -path ${imagedir}/${test_image}.png checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -1,4 +1,3 @@
puts "========================" puts "========================"
puts "BUC60703" puts "BUC60703"
puts "========================" puts "========================"
@ -8,28 +7,12 @@ puts ""
#################################### ####################################
restore [locate_data_file buc60703d.brep] a restore [locate_data_file buc60703d.brep] a
#maxtolerance a
checkshape a
restore [locate_data_file buc60703f.brep] b restore [locate_data_file buc60703f.brep] b
#maxtolerance b
checkshape b
if [catch {bfuse result a b } catch_result] { bfuse result a b
puts "Faulty BUC60703: here is problem with FUSE operation"
} else { checkshape result
puts "OK OCC348: function FUSE works ok" checkprops result -s 322.013 -v 375.942
if [catch {checkshape result} catch_result] { checknbshapes result -wire 6 -face 4 -shell 1 -solid 1
set mistake 1
} else {
set mistake 0
}
if { $mistake != 0} {
puts "Faulty BUC60703 : here is checking problem. See also OCC438: 919 D3 and D4"
} else {
puts "BUC60703 : here is NOT checking problem"
}
}
checkprops result -s 505.797
checkview -display result -2d -path ${imagedir}/${test_image}.png checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -1,7 +1,3 @@
puts "TODO 0026789 ALL: Error : The area of result shape is"
puts "TODO 0026789 ALL: Error : The volume of result shape is"
puts "TODO 0026789 ALL: Error : is WRONG because number of"
puts "========" puts "========"
puts "OCC26789" puts "OCC26789"
puts "========" puts "========"
@ -21,7 +17,7 @@ bfillds
bbop result 1 bbop result 1
checkshape result checkshape result
checknbshapes result -solid 1 -shell 2 checknbshapes result -wire 20 -face 20 -solid 1 -shell 2
checkprops result -s 3583.27 -v 11455.2 checkprops result -s 3583.27 -v 11455.2
checkview -display result -2d -path ${imagedir}/${test_image}.png checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -19,7 +19,7 @@ bfillds
bbop result 1 bbop result 1
checkshape result checkshape result
checknbshapes result -solid 1 -shell 2 checknbshapes result -wire 20 -face 20 -solid 1 -shell 2
checkprops result -s 3583.27 -v 11455.2 checkprops result -s 3583.27 -v 11455.2
checkview -display result -2d -path ${imagedir}/${test_image}.png checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -1,6 +1,3 @@
puts "TODO OCC26883 ALL: Faulty shapes in variables faulty_1 to"
puts "TODO OCC26883 ALL: Error : is WRONG because number of SOLID entities in shape"
puts "========" puts "========"
puts "OCC26883" puts "OCC26883"
puts "========" puts "========"
@ -21,7 +18,7 @@ bfillds
bbop result 1 bbop result 1
checkshape result checkshape result
checkprops result -s 2116.44 -v 607.276
checknbshapes result -solid 1 checknbshapes result -wire 39 -face 32 -shell 3 -solid 1
checkview -display result -2d -path ${imagedir}/${test_image}.png checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -1,5 +1,3 @@
puts "TODO OCC27948 ALL: ERROR: OCC27948 is reproduced."
puts "========" puts "========"
puts "OCC27948" puts "OCC27948"
puts "========" puts "========"
@ -11,18 +9,10 @@ puts ""
restore [locate_data_file bug27948_a.brep] a restore [locate_data_file bug27948_a.brep] a
restore [locate_data_file bug27948_b.brep] b restore [locate_data_file bug27948_b.brep] b
bcut res a b bcut result a b
explode res F
vinit checkshape result
vdisplay res checkprops result -s 135.137 -v 40.573
vfit checknbshapes result -wire 19 -face 17 -shell 1 -solid 1
vdisplay res_16
vsetdispmode res_16 1
set bug_info [string trim [vreadpixel 340 280 name]] checkview -display result -2d -path ${imagedir}/${test_image}.png
if {$bug_info == "DARKGOLDENROD3 1"} {
puts "ERROR: OCC27948 is reproduced."
}
checkview -screenshot -3d -path ${imagedir}/${test_image}.png

View File

@ -11,8 +11,17 @@ restore [locate_data_file bug29580_Solid.brep] b2
bfuse result b1 b2 bfuse result b1 b2
foreach f [explode result f] {
explode $f w
foreach w [explode $f w] {
if {[regexp "A self-intersecting wire" [checkselfintersection $w $f]]} {
puts "Error: BOP produces a face with self-intersecting wire"
}
}
}
checkshape result checkshape result
checknbshapes result -wire 14 -face 13 -shell 1 -solid 1 checknbshapes result -wire 11 -face 10 -shell 1 -solid 1
checkprops result -s 865.851 -v 1622.19 checkprops result -s 865.851 -v 1622.17
checkview -display result -2d -path ${imagedir}/${test_image}.png checkview -display result -2d -path ${imagedir}/${test_image}.png