diff --git a/src/IntWalk/IntWalk_PWalking.cxx b/src/IntWalk/IntWalk_PWalking.cxx index 54c42a1304..eed1c6334a 100644 --- a/src/IntWalk/IntWalk_PWalking.cxx +++ b/src/IntWalk/IntWalk_PWalking.cxx @@ -159,6 +159,35 @@ static void IsParallel(const Handle(IntSurf_LineOn2S)& theLine, theIsUparallel = ((aVmax - aVmin) < theToler); } +//======================================================================= +//function : AdjustToDomain +//purpose : Returns TRUE if theP has been changed (i.e. initial value +// was out of the domain) +//======================================================================= +static Standard_Boolean AdjustToDomain(const Standard_Integer theNbElem, + Standard_Real* theParam, + const Standard_Real* const theLowBorder, + const Standard_Real* const theUppBorder) +{ + Standard_Boolean aRetVal = Standard_False; + for (Standard_Integer i = 0; i < theNbElem; i++) + { + if ((theParam[i] - theLowBorder[i]) < -Precision::PConfusion()) + { + theParam[i] = theLowBorder[i]; + aRetVal = Standard_True; + } + + if ((theParam[i] - theUppBorder[i]) > Precision::PConfusion()) + { + theParam[i] = theUppBorder[i]; + aRetVal = Standard_True; + } + } + + return aRetVal; +} + //================================================================================== // function : IntWalk_PWalking::IntWalk_PWalking // purpose : @@ -2247,7 +2276,19 @@ Standard_Boolean IntWalk_PWalking::HandleSingleSingularPoint(const Handle(Adapto continue; anInt.Point().Parameters(thePnt(1), thePnt(2), thePnt(3), thePnt(4)); - return Standard_True; + + Standard_Boolean isInDomain = Standard_True; + for (Standard_Integer j = 1; isInDomain && (j <= 4); ++j) + { + if ((thePnt(j) - aLowBorder[j - 1] + Precision::PConfusion())* + (thePnt(j) - aUppBorder[j - 1] - Precision::PConfusion()) > 0.0) + { + isInDomain = Standard_False; + } + } + + if (isInDomain) + return Standard_True; } } @@ -2259,16 +2300,26 @@ Standard_Boolean IntWalk_PWalking::HandleSingleSingularPoint(const Handle(Adapto //purpose : //======================================================================= Standard_Boolean IntWalk_PWalking:: -SeekPointOnBoundary(const Handle(Adaptor3d_HSurface)& theASurf1, - const Handle(Adaptor3d_HSurface)& theASurf2, - const Standard_Real theU1, - const Standard_Real theV1, - const Standard_Real theU2, - const Standard_Real theV2, - const Standard_Boolean isTheFirst) + SeekPointOnBoundary(const Handle(Adaptor3d_HSurface)& theASurf1, + const Handle(Adaptor3d_HSurface)& theASurf2, + const Standard_Real theU1, + const Standard_Real theV1, + const Standard_Real theU2, + const Standard_Real theV2, + const Standard_Boolean isTheFirst) { Standard_Boolean isOK = Standard_False; + // u1, v1, u2, v2 order is used. + const Standard_Real aLowBorder[4] = {theASurf1->FirstUParameter(), + theASurf1->FirstVParameter(), + theASurf2->FirstUParameter(), + theASurf2->FirstVParameter()}; + const Standard_Real aUppBorder[4] = {theASurf1->LastUParameter(), + theASurf1->LastVParameter(), + theASurf2->LastUParameter(), + theASurf2->LastVParameter()}; + // Tune solution tolerance according with object size. const Standard_Real aRes1 = Max(Precision::PConfusion() / theASurf1->UResolution(1.0), Precision::PConfusion() / theASurf1->VResolution(1.0)); @@ -2288,21 +2339,26 @@ SeekPointOnBoundary(const Handle(Adaptor3d_HSurface)& theASurf1, { aNbIter--; aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, aPnt); - if(aStatus) + if (aStatus && !AdjustToDomain(4, &aPnt(1), &aLowBorder[0], &aUppBorder[0])) break; - aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(aPnt(3), aPnt(4)), aPnt(1), aPnt(2)); - if(aStatus) + aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(aPnt(3), aPnt(4)), + aPnt(1), aPnt(2)); + if (aStatus && !AdjustToDomain(2, &aPnt(1), &aLowBorder[0], &aUppBorder[0])) break; - aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(aPnt(1), aPnt(2)), aPnt(3), aPnt(4)); - if(aStatus) + aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(aPnt(1), aPnt(2)), + aPnt(3), aPnt(4)); + if (aStatus && !AdjustToDomain(2, &aPnt(3), &aLowBorder[2], &aUppBorder[2])) break; } while(!aStatus && (aNbIter > 0)); // Handle singular points. - Standard_Boolean aSingularStatus = HandleSingleSingularPoint(theASurf1, theASurf2, aTol, aSingularPnt); + Standard_Boolean aSingularStatus = HandleSingleSingularPoint(theASurf1, + theASurf2, + aTol, + aSingularPnt); if (aSingularStatus) aPnt = aSingularPnt; diff --git a/tests/bugs/modalg_7/bug29103 b/tests/bugs/modalg_7/bug29103 new file mode 100644 index 0000000000..33bc06ccc7 --- /dev/null +++ b/tests/bugs/modalg_7/bug29103 @@ -0,0 +1,56 @@ +puts "========" +puts "OCC29103" +puts "========" +puts "" +################################################# +# No intersection curve between faces if starting points are given +################################################# + +set MaxTolReached 2.0e-7 +set GoodNbCurv 1 +set ExpLength 0.074141742883251954 + +restore [locate_data_file bug29073_M6.brep] a +restore [locate_data_file bug29073_Shell.brep] b +explode a f +explode b f + +don b_2 +axo +fit +disp a_6 + +set log1 [bopcurves a_6 b_2 -2d] + +checkview -screenshot -2d -path ${imagedir}/${test_image}_1.png +checklength c_1 -l $ExpLength + +don b_2 +axo +fit +disp a_6 + +set log2 [bopcurves a_6 b_2 -2d -p -0.55478319275098653 1.2919191091235780 0.80333089657224976 0.67079577554162440 -p -0.62451407353846222 1.2667484772947102 0.82894736842100003 0.70523311453721027] + +checkview -screenshot -2d -path ${imagedir}/${test_image}_2.png +checklength c_1 -l $ExpLength + +regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log1} full Toler1 NbCurv1 +regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log2} full Toler2 NbCurv2 + +if {$Toler1 > $MaxTolReached} { + puts "Error: Big tolerance is returned by intersector w/o start points" +} + +if {$Toler2 > $MaxTolReached} { + puts "Error: Big tolerance is returned by intersector with start points" +} + +if {$NbCurv1 != $GoodNbCurv} { + puts "Error: Please check NbCurves for intersector w/o start points" +} + +if {$NbCurv2 != $GoodNbCurv} { + puts "Error: Please check NbCurves for intersector with start points" +} +