1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-06-05 11:24:17 +03:00

0023884: Boolean Fuse between two faces fails

fix for the bug v1
fix for the bug v1.1
Test case for issue CR23884
This commit is contained in:
pkv 2014-02-06 11:18:55 +04:00 committed by abv
parent ba76708cc0
commit a6b634c30a
2 changed files with 1232 additions and 1205 deletions

View File

@ -1173,9 +1173,8 @@ static Standard_Boolean isTreatAnalityc(const TopoDS_Face& theF1,
const Handle(Adaptor3d_TopolTool)& dom1, const Handle(Adaptor3d_TopolTool)& dom1,
const Handle(Adaptor3d_TopolTool)& dom2) const Handle(Adaptor3d_TopolTool)& dom2)
{ {
Standard_Boolean bDone, rejectSurface, reApprox, bAvoidLineConstructor, Standard_Boolean bDone, rejectSurface, reApprox, bAvoidLineConstructor;
bPCurvesOk; Standard_Boolean ok, bPCurvesOk;
Standard_Boolean ok;
Standard_Integer i, j, aNbParts; Standard_Integer i, j, aNbParts;
Standard_Real fprm, lprm; Standard_Real fprm, lprm;
Standard_Real Tolpc; Standard_Real Tolpc;
@ -1203,18 +1202,17 @@ reapprox:;
// //
const Handle(IntPatch_WLine)& aWLine= const Handle(IntPatch_WLine)& aWLine=
Handle(IntPatch_WLine)::DownCast(L); Handle(IntPatch_WLine)::DownCast(L);
#ifdef DEB_DUMPWLINE //DumpWLine(aWLine);
DumpWLine(aWLine);
#endif
anewL = ComputePurgedWLine(aWLine); anewL = ComputePurgedWLine(aWLine);
if(anewL.IsNull()) { if(anewL.IsNull()) {
return; return;
} }
L = anewL; L = anewL;
#ifdef DEB_DUMPWLINE
const Handle(IntPatch_WLine)& aWLineX = Handle(IntPatch_WLine)::DownCast(L); //const Handle(IntPatch_WLine)& aWLineX = Handle(IntPatch_WLine)::DownCast(L);
DumpWLine(aWLineX); //DumpWLine(aWLineX);
#endif
// //
if(!myListOfPnts.IsEmpty()) { if(!myListOfPnts.IsEmpty()) {
bAvoidLineConstructor = Standard_True; bAvoidLineConstructor = Standard_True;
@ -1230,7 +1228,6 @@ reapprox:;
if(P1.SquareDistance(P2) < 1.e-14) { if(P1.SquareDistance(P2) < 1.e-14) {
bAvoidLineConstructor = Standard_False; bAvoidLineConstructor = Standard_False;
} }
} }
// //
// Line Constructor // Line Constructor
@ -1424,7 +1421,8 @@ reapprox:;
if(P1.Distance(P2) > aTolDist) { if(P1.Distance(P2) > aTolDist) {
Standard_Real anewpar = fprm; Standard_Real anewpar = fprm;
if(ParameterOutOfBoundary(fprm, newc, myFace1, myFace2, lprm, Standard_False, anewpar, myContext)) { if(ParameterOutOfBoundary(fprm, newc, myFace1, myFace2,
lprm, Standard_False, anewpar, myContext)) {
fprm = anewpar; fprm = anewpar;
} }
aSeqFprm.Append(fprm); aSeqFprm.Append(fprm);
@ -1446,7 +1444,8 @@ reapprox:;
if(P1.Distance(P2) > aTolDist) { if(P1.Distance(P2) > aTolDist) {
Standard_Real anewpar = lprm; Standard_Real anewpar = lprm;
if(ParameterOutOfBoundary(lprm, newc, myFace1, myFace2, fprm, Standard_True, anewpar, myContext)) { if(ParameterOutOfBoundary(lprm, newc, myFace1, myFace2,
fprm, Standard_True, anewpar, myContext)) {
lprm = anewpar; lprm = anewpar;
} }
aSeqFprm.Append(aNul); aSeqFprm.Append(aNul);
@ -1849,14 +1848,15 @@ reapprox:;
else { // X else { // X
Standard_Boolean bIsDecomposited; Standard_Boolean bIsDecomposited;
Standard_Integer nbiter, aNbSeqOfL; Standard_Integer nbiter, aNbSeqOfL;
Standard_Real tol2d; Standard_Real tol2d, aTolApproxImp;
IntPatch_SequenceOfLine aSeqOfL; IntPatch_SequenceOfLine aSeqOfL;
GeomInt_WLApprox theapp3d; GeomInt_WLApprox theapp3d;
Approx_ParametrizationType aParType = Approx_ChordLength; Approx_ParametrizationType aParType = Approx_ChordLength;
// //
Standard_Boolean anApprox1 = myApprox1; Standard_Boolean anApprox1 = myApprox1;
Standard_Boolean anApprox2 = myApprox2; Standard_Boolean anApprox2 = myApprox2;
//
aTolApproxImp=1.e-5;
tol2d = myTolApprox; tol2d = myTolApprox;
GeomAbs_SurfaceType typs1, typs2; GeomAbs_SurfaceType typs1, typs2;
@ -1872,9 +1872,9 @@ reapprox:;
anWithPC = anWithPC =
ApproxWithPCurves(myHS2->Surface().Cylinder(), myHS1->Surface().Sphere()); ApproxWithPCurves(myHS2->Surface().Cylinder(), myHS1->Surface().Sphere());
} }
//
if(!anWithPC) { if(!anWithPC) {
//aParType = Approx_Centripetal; myTolApprox = aTolApproxImp;//1.e-5;
myTolApprox = 1.e-5;
anApprox1 = Standard_False; anApprox1 = Standard_False;
anApprox2 = Standard_False; anApprox2 = Standard_False;
// //
@ -1882,7 +1882,6 @@ reapprox:;
} }
if(myHS1 == myHS2) { if(myHS1 == myHS2) {
//
theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType); theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType);
rejectSurface = Standard_True; rejectSurface = Standard_True;
} }
@ -1894,7 +1893,6 @@ reapprox:;
// //
ApproxParameters(myHS1, myHS2, iDegMin, iDegMax, iNbIter); ApproxParameters(myHS1, myHS2, iDegMin, iDegMax, iNbIter);
theapp3d.SetParameters(myTolApprox, tol2d, iDegMin, iDegMax, iNbIter, Standard_True, aParType); theapp3d.SetParameters(myTolApprox, tol2d, iDegMin, iDegMax, iNbIter, Standard_True, aParType);
//
} }
} }
// //
@ -1909,9 +1907,9 @@ reapprox:;
aSeqOfL, aSeqOfL,
aReachedTol, aReachedTol,
myContext); myContext);
if ( bIsDecomposited && ( myTolReached3d < aReachedTol ) ) if ( bIsDecomposited && ( myTolReached3d < aReachedTol ) ) {
myTolReached3d = aReachedTol; myTolReached3d = aReachedTol;
}
// //
aNbSeqOfL=aSeqOfL.Length(); aNbSeqOfL=aSeqOfL.Length();
// //
@ -1927,9 +1925,6 @@ reapprox:;
} }
} }
// //
// nbiter=(bIsDecomposited) ? aSeqOfL.Length() :
// ((bAvoidLineConstructor) ? 1 :aNbParts);
//
for(i = 1; i <= nbiter; ++i) { for(i = 1; i <= nbiter; ++i) {
if(bIsDecomposited) { if(bIsDecomposited) {
WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i)); WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
@ -1977,18 +1972,17 @@ reapprox:;
// //
theapp3d.Perform(myHS1,myHS2,WL,Standard_True,anApprox1,anApprox2,ifprm,ilprm); theapp3d.Perform(myHS1,myHS2,WL,Standard_True,anApprox1,anApprox2,ifprm,ilprm);
} }
if (!theapp3d.IsDone()) {
// //
if (!theapp3d.IsDone()) {
Handle(Geom2d_BSplineCurve) H1; Handle(Geom2d_BSplineCurve) H1;
Handle(Geom2d_BSplineCurve) H2;
// //
Handle(Geom_Curve) aBSp=MakeBSpline(WL,ifprm, ilprm); Handle(Geom_Curve) aBSp=MakeBSpline(WL,ifprm, ilprm);
Handle(Geom2d_BSplineCurve) H2; //
if(myApprox1) { if(myApprox1) {
H1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True); H1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
} }
//
if(myApprox2) { if(myApprox2) {
H2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False); H2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
} }
@ -2012,7 +2006,6 @@ reapprox:;
myTolReached3d=1.e-6; myTolReached3d=1.e-6;
} }
} }
//
} }
else if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) { else if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) {
myTolReached3d = theapp3d.TolReached3d(); myTolReached3d = theapp3d.TolReached3d();
@ -2104,7 +2097,7 @@ reapprox:;
} }
// //
mySeqOfCurve.Append(aCurve); mySeqOfCurve.Append(aCurve);
} }//if(typs1 == GeomAbs_Plane) {
else if(typs2 == GeomAbs_Plane) { else if(typs2 == GeomAbs_Plane) {
const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j); const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
@ -2215,33 +2208,49 @@ reapprox:;
} else { } else {
mySeqOfCurve.Append(aCurve); mySeqOfCurve.Append(aCurve);
} }
} }// else if(typs2 == GeomAbs_Plane)
else { //
else { //typs2 != GeomAbs_Plane && typs1 != GeomAbs_Plane
Standard_Boolean bIsValid1, bIsValid2;
Handle(Geom_BSplineCurve) BS;
Handle(Geom2d_BSplineCurve) aH2D;
IntTools_Curve aCurve;
//
bIsValid1=Standard_True;
bIsValid2=Standard_True;
//
const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j); const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
nbpoles = mbspc.NbPoles(); nbpoles = mbspc.NbPoles();
TColgp_Array1OfPnt tpoles(1,nbpoles); TColgp_Array1OfPnt tpoles(1,nbpoles);
mbspc.Curve(1,tpoles); mbspc.Curve(1,tpoles);
Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles, BS=new Geom_BSplineCurve(tpoles,
mbspc.Knots(), mbspc.Knots(),
mbspc.Multiplicities(), mbspc.Multiplicities(),
mbspc.Degree()); mbspc.Degree());
GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK); GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
Check.FixTangent(Standard_True,Standard_True); Check.FixTangent(Standard_True,Standard_True);
// //
IntTools_Curve aCurve;
aCurve.SetCurve(BS); aCurve.SetCurve(BS);
aCurve.SetFirstCurve2d(aH2D);
aCurve.SetSecondCurve2d(aH2D);
//
if(myApprox1) { if(myApprox1) {
if(anApprox1) { if(anApprox1) {
Handle(Geom2d_BSplineCurve) BS1;
TColgp_Array1OfPnt2d tpoles2d(1,nbpoles); TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
mbspc.Curve(2,tpoles2d); mbspc.Curve(2,tpoles2d);
Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d, //
BS1=new Geom2d_BSplineCurve(tpoles2d,
mbspc.Knots(), mbspc.Knots(),
mbspc.Multiplicities(), mbspc.Multiplicities(),
mbspc.Degree()); mbspc.Degree());
GeomLib_Check2dBSplineCurve newCheck(BS1,TOLCHECK,TOLANGCHECK); GeomLib_Check2dBSplineCurve newCheck(BS1,TOLCHECK,TOLANGCHECK);
newCheck.FixTangent(Standard_True,Standard_True); newCheck.FixTangent(Standard_True,Standard_True);
// //
if (!reApprox) {
bIsValid1=CheckPCurve(BS1, myFace1);
}
//
aCurve.SetFirstCurve2d(BS1); aCurve.SetFirstCurve2d(BS1);
} }
else { else {
@ -2255,24 +2264,23 @@ reapprox:;
BS1 = Handle(Geom2d_BSplineCurve)::DownCast(C2d); BS1 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
aCurve.SetFirstCurve2d(BS1); aCurve.SetFirstCurve2d(BS1);
} }
} // if(myApprox1) {
}
else {
Handle(Geom2d_BSplineCurve) H1;
// //
aCurve.SetFirstCurve2d(H1);
}
if(myApprox2) { if(myApprox2) {
if(anApprox2) { if(anApprox2) {
Handle(Geom2d_BSplineCurve) BS2;
TColgp_Array1OfPnt2d tpoles2d(1,nbpoles); TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d); mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d, BS2=new Geom2d_BSplineCurve(tpoles2d,
mbspc.Knots(), mbspc.Knots(),
mbspc.Multiplicities(), mbspc.Multiplicities(),
mbspc.Degree()); mbspc.Degree());
GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK); GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
newCheck.FixTangent(Standard_True,Standard_True); newCheck.FixTangent(Standard_True,Standard_True);
// //
if (!reApprox) {
bIsValid2=CheckPCurve(BS2, myFace2);
}
aCurve.SetSecondCurve2d(BS2); aCurve.SetSecondCurve2d(BS2);
} }
else { else {
@ -2286,12 +2294,12 @@ reapprox:;
BS2 = Handle(Geom2d_BSplineCurve)::DownCast(C2d); BS2 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
aCurve.SetSecondCurve2d(BS2); aCurve.SetSecondCurve2d(BS2);
} }
} //if(myApprox2) {
} if (!bIsValid1 || !bIsValid2) {
else { myTolApprox=aTolApproxImp;//1.e-5;
Handle(Geom2d_BSplineCurve) H2; tol2d = myTolApprox;
// reApprox = Standard_True;
aCurve.SetSecondCurve2d(H2); goto reapprox;
} }
// //
mySeqOfCurve.Append(aCurve); mySeqOfCurve.Append(aCurve);
@ -2305,6 +2313,8 @@ reapprox:;
case IntPatch_Restriction: case IntPatch_Restriction:
break; break;
default:
break;
} }
} }
@ -5025,6 +5035,7 @@ Standard_Real MaxSquareDistance (const Standard_Real aT,
const TopoDS_Face& aFace) const TopoDS_Face& aFace)
{ {
const Standard_Integer NPoints = 23; const Standard_Integer NPoints = 23;
Standard_Integer i;
Standard_Real umin,umax,vmin,vmax; Standard_Real umin,umax,vmin,vmax;
BRepTools::UVBounds(aFace, umin, umax, vmin, vmax); BRepTools::UVBounds(aFace, umin, umax, vmin, vmax);
@ -5032,18 +5043,18 @@ Standard_Real MaxSquareDistance (const Standard_Real aT,
Standard_Real tolV = Max ((vmax-vmin)*0.01, Precision::Confusion()); Standard_Real tolV = Max ((vmax-vmin)*0.01, Precision::Confusion());
Standard_Real fp = aPC->FirstParameter(); Standard_Real fp = aPC->FirstParameter();
Standard_Real lp = aPC->LastParameter(); Standard_Real lp = aPC->LastParameter();
Standard_Real step = (lp-fp)/(NPoints+1);
// adjust domain for periodic surfaces // adjust domain for periodic surfaces
TopLoc_Location aLoc; TopLoc_Location aLoc;
Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc); Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
if (aSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) if (aSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
aSurf = (Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurf))->BasisSurface(); aSurf = (Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurf))->BasisSurface();
}
gp_Pnt2d pnt = aPC->Value((fp+lp)/2); gp_Pnt2d pnt = aPC->Value((fp+lp)/2);
Standard_Real u,v; Standard_Real u,v;
pnt.Coord(u,v); pnt.Coord(u,v);
//
if (aSurf->IsUPeriodic()) { if (aSurf->IsUPeriodic()) {
Standard_Real aPer = aSurf->UPeriod(); Standard_Real aPer = aSurf->UPeriod();
Standard_Integer nshift = (Standard_Integer) ((u-umin)/aPer); Standard_Integer nshift = (Standard_Integer) ((u-umin)/aPer);
@ -5058,16 +5069,34 @@ Standard_Real MaxSquareDistance (const Standard_Real aT,
vmin += aPer*nshift; vmin += aPer*nshift;
vmax += aPer*nshift; vmax += aPer*nshift;
} }
//
Standard_Integer i; //--------------------------------------------------------
for (i=1; i <= NPoints; i++) { Standard_Boolean bRet;
Standard_Real p = fp + i * step; Standard_Integer j, aNbIntervals;
pnt = aPC->Value(p); Standard_Real aT, dT;
pnt.Coord(u,v); gp_Pnt2d aP2D;
//
Geom2dAdaptor_Curve aGAC(aPC);
aNbIntervals=aGAC.NbIntervals(GeomAbs_CN);
//
TColStd_Array1OfReal aTI(1, aNbIntervals+1);
aGAC.Intervals(aTI,GeomAbs_CN);
//
bRet=Standard_False;
//
aT=aGAC.FirstParameter();
for (j=1; j<=aNbIntervals; ++j) {
dT=(aTI(j+1)-aTI(j))/NPoints;
//
for (i=1; i<NPoints; i++) {
aT=aT+dT;
aGAC.D0(aT, aP2D);
aP2D.Coord(u,v);
if (umin-u > tolU || u-umax > tolU || if (umin-u > tolU || u-umax > tolU ||
vmin-v > tolV || v-vmax > tolV) vmin-v > tolV || v-vmax > tolV) {
return Standard_False; return bRet;
} }
return Standard_True; }
}
return !bRet;
} }

4
tests/bugs/modalg_5/bug23884 Normal file → Executable file
View File

@ -1,5 +1,3 @@
puts "TODO OCC23884 ALL: Faulty shapes in variables faulty_1 to faulty_"
puts "TODO OCC23884 ALL: Error : The square of result shape is"
puts "============" puts "============"
puts "OCC23884" puts "OCC23884"
puts "============" puts "============"
@ -14,7 +12,7 @@ restore [locate_data_file bug23884_fz124] b2
bop b1 b2 bop b1 b2
bopfuse result bopfuse result
set square 2333.14 set square 2415.65
set 2dviewer 0 set 2dviewer 0