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

0024558: Boolean operation can not create all results solids which should be built.

Corrections in checking 2d distances when splitting wires.
Test case for the issue.
This commit is contained in:
emv 2014-02-12 15:40:05 +04:00 committed by apn
parent d5f74e42d6
commit ecba6de3cc
4 changed files with 203 additions and 175 deletions

View File

@ -336,20 +336,20 @@ void Path (const GeomAdaptor_Surface& aGAS,
{ {
Standard_Integer i, j, aNb, aNbj; Standard_Integer i, j, aNb, aNbj;
Standard_Real aTol, anAngleIn, anAngleOut, anAngle, aMinAngle; Standard_Real anAngleIn, anAngleOut, anAngle, aMinAngle;
Standard_Real aTol2D, aTol2D2; Standard_Real aTol2D, aTol2D2, aD2, aTwoPI;
Standard_Real aTol2, aD2, aTwoPI;
Standard_Boolean anIsSameV2d, anIsSameV, anIsFound, anIsOut, anIsNotPassed; Standard_Boolean anIsSameV2d, anIsSameV, anIsFound, anIsOut, anIsNotPassed;
Standard_Boolean bIsClosed, bRecomputeAngle;
TopoDS_Vertex aVa, aVb; TopoDS_Vertex aVa, aVb;
TopoDS_Edge aEOuta; TopoDS_Edge aEOuta;
BOPAlgo_ListIteratorOfListOfEdgeInfo anIt; BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
BOPCol_SequenceOfReal aRecomputedAngles;
// //
aVa = aVFirst; aVa = aVFirst;
aEOuta = aEFirst; aEOuta = aEFirst;
BOPAlgo_EdgeInfo* anEdgeInfo = &aEIFirst; BOPAlgo_EdgeInfo* anEdgeInfo = &aEIFirst;
// //
aTwoPI = M_PI + M_PI; aTwoPI = M_PI + M_PI;
aTol=1.e-7;
// //
// append block // append block
// //
@ -376,27 +376,27 @@ void Path (const GeomAdaptor_Surface& aGAS,
gp_Pnt2d aPb=Coord2d(aVb, aEOuta, myFace); gp_Pnt2d aPb=Coord2d(aVb, aEOuta, myFace);
const BOPAlgo_ListOfEdgeInfo& aLEInfoVb=mySmartMap.FindFromKey(aVb); const BOPAlgo_ListOfEdgeInfo& aLEInfo=mySmartMap.FindFromKey(aVb);
// //
aTol=2.*Tolerance2D(aVb, aGAS); aTol2D = 2.*Tolerance2D(aVb, aGAS);
aTol2=10.*aTol*aTol; aTol2D2 = aTol2D * aTol2D;
//
bIsClosed = BRep_Tool::Degenerated(aEOuta) ||
BRep_Tool::IsClosed(aEOuta, myFace) || aVa.IsSame(aVb);
if (!bIsClosed) {
TopoDS_Vertex aV1, aV2; TopoDS_Vertex aV1, aV2;
TopExp::Vertices(aEOuta, aV1, aV2); //
Standard_Boolean bIsClosedEdge = aV1.IsNull() || aV2.IsNull() || aV1.IsSame(aV2); anIt.Initialize(aLEInfo);
Standard_Boolean bIsDegenerated = BRep_Tool::Degenerated(aEOuta); for (; anIt.More() && !bIsClosed; anIt.Next()) {
Standard_Boolean bIsSeam = BRep_Tool::IsClosed(aEOuta, myFace);
anIt.Initialize(aLEInfoVb);
for (; anIt.More(); anIt.Next()) {
const BOPAlgo_EdgeInfo& anEI = anIt.Value(); const BOPAlgo_EdgeInfo& anEI = anIt.Value();
const TopoDS_Edge& aE = anEI.Edge(); const TopoDS_Edge& aE = anEI.Edge();
bIsDegenerated = bIsDegenerated || BRep_Tool::Degenerated(aE); //
bIsSeam = bIsSeam || BRep_Tool::IsClosed(aE, myFace); bIsClosed = BRep_Tool::Degenerated(aE) || BRep_Tool::IsClosed(aE, myFace);
aV1.Nullify(); if (!bIsClosed) {
aV2.Nullify();
TopExp::Vertices(aE, aV1, aV2); TopExp::Vertices(aE, aV1, aV2);
bIsClosedEdge = bIsClosedEdge || aV1.IsNull() || aV2.IsNull() || aV1.IsSame(aV2); bIsClosed = aV1.IsNull() || aV2.IsNull() || aV1.IsSame(aV2);
}
}
} }
// //
aNb=aLS.Length(); aNb=aLS.Length();
@ -411,26 +411,23 @@ void Path (const GeomAdaptor_Surface& aGAS,
aBuf.Append(aEPrev); aBuf.Append(aEPrev);
anIsSameV=aVPrev.IsSame(aVb); anIsSameV = aVPrev.IsSame(aVb);
anIsSameV2d=Standard_False; anIsSameV2d = anIsSameV;
if (anIsSameV) { if (anIsSameV) {
anIsSameV2d = Standard_True; if(bIsClosed) {
// aD2 = aPaPrev.SquareDistance(aPb);
aD2=aPaPrev.SquareDistance(aPb); anIsSameV2d = aD2 < aTol2D2;
anIsSameV2d =aD2<aTol2; if (anIsSameV2d) {
if(anIsSameV2d &&
(bIsDegenerated || bIsSeam || bIsClosedEdge)) {
Standard_Real udist = fabs(aPaPrev.X() - aPb.X()); Standard_Real udist = fabs(aPaPrev.X() - aPb.X());
Standard_Real vdist = fabs(aPaPrev.Y() - aPb.Y()); Standard_Real vdist = fabs(aPaPrev.Y() - aPb.Y());
Standard_Real aTolU = 2. * UTolerance2D(aVb, aGAS); Standard_Real aTolU = 2.*UTolerance2D(aVb, aGAS);
Standard_Real aTolV = 2. * VTolerance2D(aVb, aGAS); Standard_Real aTolV = 2.*VTolerance2D(aVb, aGAS);
// //
if((udist > aTolU) || if((udist > aTolU) || (vdist > aTolV)) {
(vdist > aTolV)) {
anIsSameV2d = Standard_False; anIsSameV2d = Standard_False;
} }
} }
}
}//if (anIsSameV) { }//if (anIsSameV) {
// //
if (anIsSameV && anIsSameV2d) { if (anIsSameV && anIsSameV2d) {
@ -481,26 +478,17 @@ void Path (const GeomAdaptor_Surface& aGAS,
} }
} }
// //
aTol2D=2.*Tolerance2D(aVb, aGAS); aRecomputedAngles.Clear();
aTol2D2=1000.*aTol2D*aTol2D;//100.*aTol2D*aTol2D; bRecomputeAngle =
//
// anAngleIn in Vb from edge aEOuta
const BOPAlgo_ListOfEdgeInfo& aLEInfo=mySmartMap.FindFromKey(aVb);
//
anAngleIn=AngleIn(aEOuta, aLEInfo);
BOPCol_SequenceOfReal aRecomputedAngles;
Standard_Boolean bRecomputeAngle =
RecomputeAngles(aLEInfo, myFace, aPb, aVb, aGAS, aEOuta, RecomputeAngles(aLEInfo, myFace, aPb, aVb, aGAS, aEOuta,
(bIsDegenerated || bIsSeam || bIsClosedEdge), bIsClosed, aTol2D, aRecomputedAngles);
aTol2D, aRecomputedAngles);
// //
// aEOutb // aEOutb
BOPAlgo_EdgeInfo *pEdgeInfo=NULL; BOPAlgo_EdgeInfo *pEdgeInfo=NULL;
// //
aMinAngle=100.; anAngleIn = AngleIn(aEOuta, aLEInfo);
anIsFound=Standard_False; aMinAngle = 100.;
anIsFound = Standard_False;
Standard_Integer aCurIndexE = 0; Standard_Integer aCurIndexE = 0;
anIt.Initialize(aLEInfo); anIt.Initialize(aLEInfo);
for (; anIt.More(); anIt.Next()) { for (; anIt.More(); anIt.Next()) {
@ -532,17 +520,19 @@ void Path (const GeomAdaptor_Surface& aGAS,
if (aE.IsSame(aEOuta)) { if (aE.IsSame(aEOuta)) {
anAngle = aTwoPI; anAngle = aTwoPI;
} else { } else {
// Look for minimal angle and make the choice. //check 2d distance
if (bIsClosed) {
gp_Pnt2d aP2Dx; gp_Pnt2d aP2Dx;
// //
aP2Dx=Coord2dVf(aE, myFace); aP2Dx = Coord2dVf(aE, myFace);
// //
aD2=aP2Dx.SquareDistance(aPb); aD2 = aP2Dx.SquareDistance(aPb);
if (aD2 > aTol2D2){ if (aD2 > aTol2D2){
continue; continue;
} }
}
// //
// // Look for minimal angle and make the choice.
anAngleOut=anEI.Angle(); anAngleOut=anEI.Angle();
// //
if(bRecomputeAngle) { if(bRecomputeAngle) {

View File

@ -512,11 +512,11 @@ void BRepFeat::FaceUntil(const TopoDS_Shape& Sbase,
} }
else if (styp == STANDARD_TYPE(Geom_CylindricalSurface)) { else if (styp == STANDARD_TYPE(Geom_CylindricalSurface)) {
str = new Geom_RectangularTrimmedSurface str = new Geom_RectangularTrimmedSurface
(s, 0., 2.*M_PI, bnd, -bnd, Standard_True, Standard_True); (s, bnd, -bnd, Standard_False, Standard_True);
} }
else if (styp == STANDARD_TYPE(Geom_ConicalSurface)) { else if (styp == STANDARD_TYPE(Geom_ConicalSurface)) {
str = new Geom_RectangularTrimmedSurface str = new Geom_RectangularTrimmedSurface
(s, 0., 2.*M_PI, bnd, -bnd, Standard_True, Standard_True); (s, bnd, -bnd, Standard_False, Standard_True);
} }
else { else {
FUntil.Nullify(); FUntil.Nullify();

View File

@ -135,10 +135,14 @@ void IntTools_EdgeEdge::Prepare()
aDt = (aT2 - aT1) / 10.; aDt = (aT2 - aT1) / 10.;
aT = aT1; aT = aT1;
aBAC.D1(aT, aP, aV1); aBAC.D1(aT, aP, aV1);
while (aT <= aT2) { while (aT < aT2) {
aT += aDt; aT += aDt;
aBAC.D1(aT, aP, aV2); aBAC.D1(aT, aP, aV2);
aC += aV1.Angle(aV2); if (aV1.Magnitude() > gp::Resolution() &&
aV2.Magnitude() > gp::Resolution()) {
gp_Dir aD1(aV1), aD2(aV2);
aC += aD1.Angle(aD2);
}
aV1 = aV2; aV1 = aV2;
} }
} }

View File

@ -0,0 +1,34 @@
puts "========="
puts "OCC24558"
puts "========="
puts ""
###########################################################
# Boolean operation can not create all results solids which should be built.
###########################################################
restore [locate_data_file bug24558_Box.brep] b1
restore [locate_data_file bug24558_Surface_1.brep] s1
restore [locate_data_file bug24558_Surface_2.brep] s2
restore [locate_data_file bug24558_Surface_3.brep] s3
restore [locate_data_file bug24558_Surface_4.brep] s4
bclearobjects
bcleartools
baddobjects b1 s1 s2 s3 s4
bfillds
bbuild result
set square 134338
set nb_v_good 109
set nb_e_good 189
set nb_w_good 95
set nb_f_good 88
set nb_sh_good 11
set nb_sol_good 5
set nb_compsol_good 0
set nb_compound_good 1
set nb_shape_good 498
set 2dviewer 1