1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00

0024823: Hang up in "bopcheck" command

Modifications:
class IntTools_EdgeEdge
 1. method
   Standard_Boolean IntTools_EdgeEdge::FindParameters(
      const BRepAdaptor_Curve& theB
      const Standard_Real aT1,
      const Standard_Real aT2,
      const Standard_Real theRes,
      const Standard_Real thePTol,
      const Bnd_Box& theCBox,
      Standard_Real& aTB1,
      Standard_Real& aTB2)

   Added protection for large values of parameters of the edges.

 2. methods
    static Standard_Boolean BndCommon(const Bnd_Box& theB1,
                                      const Bnd_Box& theB2,
                                      Bnd_Box& theBOut)
   and
    IntTools_EdgeEdge::FindSolutions()

   have been removed as redundant.

Test case for issue CR24823
This commit is contained in:
emv 2014-04-17 19:14:50 +04:00 committed by abv
parent 6092c0c8c4
commit a743e2e5e8
7 changed files with 58 additions and 96 deletions

View File

@ -127,7 +127,7 @@ Standard_Integer bopcheck
Standard_Integer iErr, aTypeInt, i, ind, j, nI1, nI2; Standard_Integer iErr, aTypeInt, i, ind, j, nI1, nI2;
Standard_Boolean bSelfInt, bFFInt; Standard_Boolean bSelfInt, bFFInt;
// //
if (theLevelOfCheck >= 0 && theLevelOfCheck < aNbInterfTypes) { if (theLevelOfCheck >= 0 && theLevelOfCheck < (aNbInterfTypes-1)) {
di << "Info:\nThe level of check is set to " di << "Info:\nThe level of check is set to "
<< type[theLevelOfCheck] << ", i.e. intersection(s)\n"; << type[theLevelOfCheck] << ", i.e. intersection(s)\n";
for (i=theLevelOfCheck+1; i<aNbInterfTypes; ++i) { for (i=theLevelOfCheck+1; i<aNbInterfTypes; ++i) {

View File

@ -125,14 +125,8 @@ is
---Purpose: ---Purpose:
-- Computes Line/Line intersection. -- Computes Line/Line intersection.
FindSolutions(me:out)
is protected;
---Purpose:
-- Looking for solutions
FindSolutions(me:out; FindSolutions(me:out;
theR1, theR2 : Range from IntTools; theR1, theR2 : Range from IntTools;
theBC : Box from Bnd;
theRanges1 : out SequenceOfRanges from IntTools; theRanges1 : out SequenceOfRanges from IntTools;
theRanges2 : out SequenceOfRanges from IntTools) theRanges2 : out SequenceOfRanges from IntTools)
is protected; is protected;
@ -149,6 +143,7 @@ is
theBAC : Curve from BRepAdaptor; theBAC : Curve from BRepAdaptor;
aT1,aT2 : Real from Standard; aT1,aT2 : Real from Standard;
theRes : Real from Standard; theRes : Real from Standard;
thePTol : Real from Standard;
theCBox : Box from Bnd; theCBox : Box from Bnd;
aTB1,aTB2 : out Real from Standard) aTB1,aTB2 : out Real from Standard)
returns Boolean from Standard returns Boolean from Standard
@ -220,6 +215,9 @@ fields
myRes1 : Real from Standard is protected; myRes1 : Real from Standard is protected;
myRes2 : Real from Standard is protected; myRes2 : Real from Standard is protected;
myPTol1 : Real from Standard is protected;
myPTol2 : Real from Standard is protected;
myRange1 : Range from IntTools is protected; myRange1 : Range from IntTools is protected;
myRange2 : Range from IntTools is protected; myRange2 : Range from IntTools is protected;

View File

@ -33,10 +33,6 @@
#include <IntTools_CommonPrt.hxx> #include <IntTools_CommonPrt.hxx>
static
Standard_Boolean BndCommon(const Bnd_Box& theB1,
const Bnd_Box& theB2,
Bnd_Box& theBOut);
static static
void BndBuildBox(const BRepAdaptor_Curve& theBAC, void BndBuildBox(const BRepAdaptor_Curve& theBAC,
const Standard_Real aT1, const Standard_Real aT1,
@ -177,9 +173,22 @@ void IntTools_EdgeEdge::Prepare()
myRes2 = myCurve2.Resolution(myTol); myRes2 = myCurve2.Resolution(myTol);
// //
if (iCT1 != 0 || iCT2 != 0) { if (iCT1 != 0 || iCT2 != 0) {
Standard_Real f, l; Standard_Real f, l, aTM;
//
myGeom1 = BRep_Tool::Curve(myEdge1, f, l); myGeom1 = BRep_Tool::Curve(myEdge1, f, l);
myGeom2 = BRep_Tool::Curve(myEdge2, f, l); myGeom2 = BRep_Tool::Curve(myEdge2, f, l);
//
myPTol1 = 5.e-13;
aTM = Max(fabs(myRange1.First()), fabs(myRange1.Last()));
if (aTM > 999.) {
myPTol1 = 5.e-16 * aTM;
}
//
myPTol2 = 5.e-13;
aTM = Max(fabs(myRange2.First()), fabs(myRange2.Last()));
if (aTM > 999.) {
myPTol2 = 5.e-16 * aTM;
}
} }
} }
@ -205,37 +214,12 @@ void IntTools_EdgeEdge::Perform()
return; return;
} }
// //
//3.2. Find solutions
FindSolutions();
}
//=======================================================================
//function : FindSolutions
//purpose :
//=======================================================================
void IntTools_EdgeEdge::FindSolutions()
{
//1. Build common box for edges
Standard_Real aT11, aT12, aT21, aT22;
Bnd_Box aB1, aB2, aBC;
//
myRange1.Range(aT11, aT12);
myRange2.Range(aT21, aT22);
//
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
//
if (!BndCommon(aB1, aB2, aBC)) {
// No intersections at all
return;
}
//
IntTools_SequenceOfRanges aRanges1, aRanges2; IntTools_SequenceOfRanges aRanges1, aRanges2;
// //
//2. Find ranges containig solutions //3.2. Find ranges containig solutions
FindSolutions(myRange1, myRange2, aBC, aRanges1, aRanges2); FindSolutions(myRange1, myRange2, aRanges1, aRanges2);
// //
//3. Merge solutions and save common parts //4. Merge solutions and save common parts
MergeSolutions(aRanges1, aRanges2); MergeSolutions(aRanges1, aRanges2);
} }
@ -245,7 +229,6 @@ void IntTools_EdgeEdge::FindSolutions()
//======================================================================= //=======================================================================
void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1, void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
const IntTools_Range& theR2, const IntTools_Range& theR2,
const Bnd_Box& theBC,
IntTools_SequenceOfRanges& theRanges1, IntTools_SequenceOfRanges& theRanges1,
IntTools_SequenceOfRanges& theRanges2) IntTools_SequenceOfRanges& theRanges2)
{ {
@ -258,7 +241,13 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
// //
theR1.Range(aT11, aT12); theR1.Range(aT11, aT12);
theR2.Range(aT21, aT22); theR2.Range(aT21, aT22);
aB1 = theBC; //
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
if (aB1.IsOut(aB2)) {
//no intersection;
return;
}
// //
bOut = Standard_False; bOut = Standard_False;
bThin = Standard_False; bThin = Standard_False;
@ -267,21 +256,20 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
iCom = 1; iCom = 1;
// //
do { do {
bOut = !FindParameters(myCurve2, aT21, aT22, myRes2, aB1, aTB21, aTB22); bOut = !FindParameters(myCurve2, aT21, aT22, myRes2, myPTol2, aB1, aTB21, aTB22);
if (bOut) { if (bOut) {
break; break;
} }
// //
bThin = (aTB22 - aTB21) < myRes2; bThin = (aTB22 - aTB21) < myRes2;
if (bThin) { if (bThin) {
bOut = !FindParameters(myCurve1, aT11, aT12, myRes1, aB1, aTB11, aTB12); bOut = !FindParameters(myCurve1, aT11, aT12, myRes1, myPTol1, aB1, aTB11, aTB12);
break; break;
} }
// //
BndBuildBox(myCurve2, aTB21, aTB22, myTol2, aB2); BndBuildBox(myCurve2, aTB21, aTB22, myTol2, aB2);
BndCommon(aB1, aB2, aB2);
// //
bOut = !FindParameters(myCurve1, aT11, aT12, myRes1, aB2, aTB11, aTB12); bOut = !FindParameters(myCurve1, aT11, aT12, myRes1, myPTol1, aB2, aTB11, aTB12);
if (bOut) { if (bOut) {
break; break;
} }
@ -305,7 +293,7 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
bStop = Standard_True; bStop = Standard_True;
} else { } else {
BndBuildBox(myCurve1, aTB11, aTB12, myTol1, aB1); BndBuildBox(myCurve1, aTB11, aTB12, myTol1, aB1);
bOut = !BndCommon(aB1, aB2, aB1); bOut = aB1.IsOut(aB2);
if (bOut) { if (bOut) {
break; break;
} }
@ -365,17 +353,12 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
IntTools_SequenceOfRanges aSegments1; IntTools_SequenceOfRanges aSegments1;
// //
IntTools_Range aR2(aT21, aT22); IntTools_Range aR2(aT21, aT22);
BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
// //
SplitRangeOnSegments(aT11, aT12, myRes1, 3, aSegments1); SplitRangeOnSegments(aT11, aT12, myRes1, 3, aSegments1);
aNb1 = aSegments1.Length(); aNb1 = aSegments1.Length();
for (i = 1; i <= aNb1; ++i) { for (i = 1; i <= aNb1; ++i) {
const IntTools_Range& aR1 = aSegments1(i); const IntTools_Range& aR1 = aSegments1(i);
aR1.Range(aT11, aT12); FindSolutions(aR1, aR2, theRanges1, theRanges2);
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
if (BndCommon(aB1, aB2, aB1)) {
FindSolutions(aR1, aR2, aB1, theRanges1, theRanges2);
}
} }
} }
@ -387,6 +370,7 @@ Standard_Boolean IntTools_EdgeEdge::FindParameters(const BRepAdaptor_Curve& theB
const Standard_Real aT1, const Standard_Real aT1,
const Standard_Real aT2, const Standard_Real aT2,
const Standard_Real theRes, const Standard_Real theRes,
const Standard_Real thePTol,
const Bnd_Box& theCBox, const Bnd_Box& theCBox,
Standard_Real& aTB1, Standard_Real& aTB1,
Standard_Real& aTB2) Standard_Real& aTB2)
@ -394,14 +378,13 @@ Standard_Boolean IntTools_EdgeEdge::FindParameters(const BRepAdaptor_Curve& theB
Standard_Boolean bRet; Standard_Boolean bRet;
Standard_Integer aC, i, k; Standard_Integer aC, i, k;
Standard_Real aCf, aDiff, aDt, aT, aTB, aTOut, aTIn; Standard_Real aCf, aDiff, aDt, aT, aTB, aTOut, aTIn;
Standard_Real aDist, aDistP, aDistTol, aPTol, aTol; Standard_Real aDist, aDistP, aDistTol, aTol;
gp_Pnt aP; gp_Pnt aP;
Bnd_Box aCBx; Bnd_Box aCBx;
// //
bRet = Standard_False; bRet = Standard_False;
aCf = 0.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.))/2.; aCf = 0.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.))/2.;
aDt = theRes; aDt = theRes;
aPTol = theRes * 0.001;
aTol = theBAC.Tolerance(); aTol = theBAC.Tolerance();
aDistP = 0.; aDistP = 0.;
aDistTol = Precision::PConfusion(); aDistTol = Precision::PConfusion();
@ -450,7 +433,7 @@ Standard_Boolean IntTools_EdgeEdge::FindParameters(const BRepAdaptor_Curve& theB
aTIn = aTB; aTIn = aTB;
aTOut = aTB - aC*aDt; aTOut = aTB - aC*aDt;
aDiff = aTIn - aTOut; aDiff = aTIn - aTOut;
while (fabs(aDiff) > aPTol) { while (fabs(aDiff) > thePTol) {
aTB = aTOut + aDiff*aCf; aTB = aTOut + aDiff*aCf;
theBAC.D0(aTB, aP); theBAC.D0(aTB, aP);
if (aCBx.IsOut(aP)) { if (aCBx.IsOut(aP)) {
@ -573,7 +556,7 @@ void IntTools_EdgeEdge::FindBestSolution(const Standard_Real aT11,
Standard_Real& aT2) Standard_Real& aT2)
{ {
Standard_Integer i, aNbS, iErr; Standard_Integer i, aNbS, iErr;
Standard_Real aDMin, aD, aCrit, aMinStep, aTMax; Standard_Real aDMin, aD, aCrit;
Standard_Real aT1x, aT2x, aT1p, aT2p; Standard_Real aT1x, aT2x, aT1p, aT2p;
GeomAPI_ProjectPointOnCurve aProj; GeomAPI_ProjectPointOnCurve aProj;
IntTools_SequenceOfRanges aSeg1; IntTools_SequenceOfRanges aSeg1;
@ -584,11 +567,6 @@ void IntTools_EdgeEdge::FindBestSolution(const Standard_Real aT11,
aDMin = 100.; aDMin = 100.;
aD = 100.; aD = 100.;
aCrit = 0.;//1.e-16; aCrit = 0.;//1.e-16;
aMinStep = 5.e-13;
aTMax = Max(fabs(aT11), fabs(aT12));
if (aTMax > 999.) {
aMinStep = 5.e-16 * aTMax;
}
// //
aNbS = 10; aNbS = 10;
SplitRangeOnSegments(aT11, aT12, 3*myRes1, aNbS, aSeg1); SplitRangeOnSegments(aT11, aT12, 3*myRes1, aNbS, aSeg1);
@ -599,7 +577,7 @@ void IntTools_EdgeEdge::FindBestSolution(const Standard_Real aT11,
const IntTools_Range& aR1 = aSeg1(i); const IntTools_Range& aR1 = aSeg1(i);
aR1.Range(aT1x, aT2x); aR1.Range(aT1x, aT2x);
// //
iErr = FindDistPC(aT1x, aT2x, myGeom1, aCrit, aMinStep, iErr = FindDistPC(aT1x, aT2x, myGeom1, aCrit, myPTol1,
aProj, aD, aT1p, aT2p, Standard_False); aProj, aD, aT1p, aT2p, Standard_False);
if (iErr != 1 && aD < aDMin) { if (iErr != 1 && aD < aDMin) {
aT1 = aT1p; aT1 = aT1p;
@ -1065,34 +1043,6 @@ void SplitRangeOnSegments(const Standard_Real aT1,
theSegments.Append(aR); theSegments.Append(aR);
} }
//=======================================================================
//function : BndCommon
//purpose :
//=======================================================================
Standard_Boolean BndCommon(const Bnd_Box& theB1,
const Bnd_Box& theB2,
Bnd_Box& theBOut)
{
Standard_Boolean bRet;
//
bRet = !theB1.IsOut(theB2);
if (bRet) {
Standard_Real aXmin1, aYmin1, aZmin1, aXmax1, aYmax1, aZmax1,
aXmin2, aYmin2, aZmin2, aXmax2, aYmax2, aZmax2;
Bnd_Box aBCom;
//
theB1.Get(aXmin1, aYmin1, aZmin1, aXmax1, aYmax1, aZmax1);
theB2.Get(aXmin2, aYmin2, aZmin2, aXmax2, aYmax2, aZmax2);
//
aBCom.Update(Max(aXmin1, aXmin2), Max(aYmin1, aYmin2), Max(aZmin1, aZmin2),
Min(aXmax1, aXmax2), Min(aYmax1, aYmax2), Min(aZmax1, aZmax2));
//
aBCom.Get(aXmin1, aYmin1, aZmin1, aXmax1, aYmax1, aZmax1);
theBOut = aBCom;
}
return bRet;
}
//======================================================================= //=======================================================================
//function : BndBuildBox //function : BndBuildBox
//purpose : //purpose :

View File

@ -26,6 +26,8 @@ inline IntTools_EdgeEdge::IntTools_EdgeEdge()
myTol(0.), myTol(0.),
myRes1(0.), myRes1(0.),
myRes2(0.), myRes2(0.),
myPTol1(0.),
myPTol2(0.),
myRange1(0., 0.), myRange1(0., 0.),
myRange2(0., 0.), myRange2(0., 0.),
mySwap(Standard_False), mySwap(Standard_False),
@ -46,6 +48,8 @@ inline IntTools_EdgeEdge::IntTools_EdgeEdge(const TopoDS_Edge& theEdge1,
myTol(0.), myTol(0.),
myRes1(0.), myRes1(0.),
myRes2(0.), myRes2(0.),
myPTol1(0.),
myPTol2(0.),
myRange1(0., 0.), myRange1(0., 0.),
myRange2(0., 0.), myRange2(0., 0.),
mySwap(Standard_False), mySwap(Standard_False),
@ -70,6 +74,8 @@ inline IntTools_EdgeEdge::IntTools_EdgeEdge(const TopoDS_Edge& theEdge1,
myTol(0.), myTol(0.),
myRes1(0.), myRes1(0.),
myRes2(0.), myRes2(0.),
myPTol1(0.),
myPTol2(0.),
myRange1(aT11, aT12), myRange1(aT11, aT12),
myRange2(aT21, aT22), myRange2(aT21, aT22),
mySwap(Standard_False), mySwap(Standard_False),

10
tests/bugs/modalg_5/bug24823 Executable file
View File

@ -0,0 +1,10 @@
puts "============"
puts "OCC24823"
puts "============"
puts ""
###############################
## Hang up in "bopcheck" command
###############################
restore [locate_data_file buc60555d.brep] b
bopcheck b

View File

@ -1,9 +1,8 @@
puts "================" puts "================"
puts "OCC26" puts "OCC26"
puts "================" puts "================"
puts "" puts ""
puts "TODO OCC12345 ALL: Error : The square of result shape is" puts "TODO OCC12345 Windows: Error : The square of result shape is"
restore [locate_data_file OCC26.brep] a restore [locate_data_file OCC26.brep] a
explode a explode a

View File

@ -1,9 +1,8 @@
puts "================" puts "================"
puts "OCC26" puts "OCC26"
puts "================" puts "================"
puts "" puts ""
puts "TODO OCC12345 ALL: Error : The square of result shape is"
restore [locate_data_file OCC26.brep] a restore [locate_data_file OCC26.brep] a
explode a explode a
checkshape a_1 checkshape a_1