mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-04 18:06:22 +03:00
0030787: BRepOffsetAPI_MakePipeShell: hangs on the attached model
Protect IntTools_EdgeEdge::FindSolutions method from cases where splitting edge on parts does not give bounding box decreasing. Use at least Epsilon from edges parameters as a step in BRepLib::FindValidRange. Test case for the issue.
This commit is contained in:
parent
3c1b70842d
commit
88c3accd1a
@ -55,6 +55,8 @@ static Standard_Boolean findNearestValidPoint(
|
||||
//
|
||||
// the general step is computed using general curve resolution
|
||||
Standard_Real aStep = theCurve.Resolution(theTol) * 1.01;
|
||||
if (aStep < theEps)
|
||||
aStep = theEps;
|
||||
// aD1Mag is a threshold to consider local derivative magnitude too small
|
||||
// and to accelerate going out of sphere
|
||||
// (inverse of resolution is the maximal derivative);
|
||||
@ -159,11 +161,19 @@ Standard_Boolean BRepLib::FindValidRange
|
||||
if (theParV2 - theParV1 < Precision::PConfusion())
|
||||
return Standard_False;
|
||||
|
||||
Standard_Real anEps = Max(Max(theCurve.Resolution(theTolE) * 0.1,
|
||||
Epsilon(Max(Abs(theParV1), Abs(theParV2)))),
|
||||
Precision::PConfusion());
|
||||
Standard_Boolean isInfParV1 = Precision::IsInfinite (theParV1),
|
||||
isInfParV2 = Precision::IsInfinite (theParV2);
|
||||
|
||||
if (Precision::IsInfinite(theParV1))
|
||||
Standard_Real aMaxPar = 0.0;
|
||||
if (!isInfParV1)
|
||||
aMaxPar = Abs (theParV1);
|
||||
if (!isInfParV2)
|
||||
aMaxPar = Max (aMaxPar, Abs (theParV2));
|
||||
|
||||
Standard_Real anEps = Max (Max (theCurve.Resolution (theTolE) * 0.1, Epsilon (aMaxPar)),
|
||||
Precision::PConfusion());
|
||||
|
||||
if (isInfParV1)
|
||||
theFirst = theParV1;
|
||||
else
|
||||
{
|
||||
@ -174,7 +184,7 @@ Standard_Boolean BRepLib::FindValidRange
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
if (Precision::IsInfinite(theParV2))
|
||||
if (isInfParV2)
|
||||
theLast = theParV2;
|
||||
else
|
||||
{
|
||||
|
@ -304,7 +304,7 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
|
||||
{
|
||||
Standard_Boolean bIsClosed2;
|
||||
Standard_Real aT11, aT12, aT21, aT22;
|
||||
Bnd_Box aB2;
|
||||
Bnd_Box aB1, aB2;
|
||||
//
|
||||
bSplit2 = Standard_False;
|
||||
myRange1.Range(aT11, aT12);
|
||||
@ -313,7 +313,6 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
|
||||
bIsClosed2 = IsClosed(myGeom2, aT21, aT22, myTol2, myRes2);
|
||||
//
|
||||
if (bIsClosed2) {
|
||||
Bnd_Box aB1;
|
||||
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
|
||||
//
|
||||
gp_Pnt aP = myGeom2->Value(aT21);
|
||||
@ -321,8 +320,9 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
|
||||
}
|
||||
//
|
||||
if (!bIsClosed2) {
|
||||
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
|
||||
BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
|
||||
FindSolutions(myRange1, myRange2, aB2, theRanges1, theRanges2);
|
||||
FindSolutions(myRange1, aB1, myRange2, aB2, theRanges1, theRanges2);
|
||||
return;
|
||||
}
|
||||
//
|
||||
@ -343,10 +343,11 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
|
||||
//
|
||||
for (i = 1; i <= aNb1; ++i) {
|
||||
const IntTools_Range& aR1 = aSegments1(i);
|
||||
BndBuildBox(myCurve1, aR1.First(), aR1.Last(), myTol1, aB1);
|
||||
for (j = 1; j <= aNb2; ++j) {
|
||||
const IntTools_Range& aR2 = aSegments2(j);
|
||||
BndBuildBox(myCurve2, aR2.First(), aR2.Last(), myTol2, aB2);
|
||||
FindSolutions(aR1, aR2, aB2, theRanges1, theRanges2);
|
||||
FindSolutions(aR1, aB1, aR2, aB2, theRanges1, theRanges2);
|
||||
}
|
||||
}
|
||||
//
|
||||
@ -358,6 +359,7 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
|
||||
const Bnd_Box& theBox1,
|
||||
const IntTools_Range& theR2,
|
||||
const Bnd_Box& theBox2,
|
||||
IntTools_SequenceOfRanges& theRanges1,
|
||||
@ -373,6 +375,7 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
|
||||
theR1.Range(aT11, aT12);
|
||||
theR2.Range(aT21, aT22);
|
||||
//
|
||||
aB1 = theBox1;
|
||||
aB2 = theBox2;
|
||||
//
|
||||
bThin = Standard_False;
|
||||
@ -385,9 +388,7 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
|
||||
aTB21 = aT21;
|
||||
aTB22 = aT22;
|
||||
//
|
||||
//1. Build box for first edge and find parameters
|
||||
// of the second one in that box
|
||||
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
|
||||
//1. Find parameters of the second edge in the box of first one
|
||||
bOut = aB1.IsOut(aB2);
|
||||
if (bOut) {
|
||||
break;
|
||||
@ -435,7 +436,9 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
|
||||
((aT21 - aTB21) < aSmallStep2) && ((aTB22 - aT22) < aSmallStep2)) {
|
||||
bStop = Standard_True;
|
||||
}
|
||||
//
|
||||
else
|
||||
BndBuildBox (myCurve1, aT11, aT12, myTol1, aB1);
|
||||
|
||||
} while (!bStop);
|
||||
//
|
||||
if (bOut) {
|
||||
@ -498,13 +501,20 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
|
||||
Standard_Integer i, aNb1;
|
||||
IntTools_SequenceOfRanges aSegments1;
|
||||
//
|
||||
// Build box for first curve to compare
|
||||
// the boxes of the splits with this one
|
||||
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
|
||||
const Standard_Real aB1SqExtent = aB1.SquareExtent();
|
||||
//
|
||||
IntTools_Range aR2(aT21, aT22);
|
||||
BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
|
||||
//
|
||||
aNb1 = SplitRangeOnSegments(aT11, aT12, myRes1, 3, aSegments1);
|
||||
for (i = 1; i <= aNb1; ++i) {
|
||||
const IntTools_Range& aR1 = aSegments1(i);
|
||||
FindSolutions(aR1, aR2, aB2, theRanges1, theRanges2);
|
||||
BndBuildBox(myCurve1, aR1.First(), aR1.Last(), myTol1, aB1);
|
||||
if (!aB1.IsOut(aB2) && (aNb1 == 1 || aB1.SquareExtent() < aB1SqExtent))
|
||||
FindSolutions(aR1, aB1, aR2, aB2, theRanges1, theRanges2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,8 @@ protected:
|
||||
|
||||
|
||||
//! Looking for the exact intersection ranges
|
||||
Standard_EXPORT void FindSolutions (const IntTools_Range& theR1,
|
||||
Standard_EXPORT void FindSolutions (
|
||||
const IntTools_Range& theR1, const Bnd_Box& theBox1,
|
||||
const IntTools_Range& theR2, const Bnd_Box& theBox2,
|
||||
IntTools_SequenceOfRanges& theRanges1, IntTools_SequenceOfRanges& theRanges2);
|
||||
|
||||
|
21
tests/bugs/modalg_7/bug30787
Normal file
21
tests/bugs/modalg_7/bug30787
Normal file
@ -0,0 +1,21 @@
|
||||
puts "TODO OCC30808 ALL: \\*\\* Exception \\*\\*.*"
|
||||
puts "TODO OCC30808 ALL: An exception was caught"
|
||||
puts "TODO OCC30808 ALL:TEST INCOMPLETE"
|
||||
|
||||
puts "========"
|
||||
puts "0030787: BRepOffsetAPI_MakePipeShell: hangs on the attached model"
|
||||
puts "========"
|
||||
puts ""
|
||||
|
||||
cpulimit 300
|
||||
|
||||
circle profile 0 -1.81898940354586e-12 0 0 -0.999995598293478 -0.00296705134258169 1 0 0 25
|
||||
mkedge profile profile
|
||||
wire profile profile
|
||||
|
||||
restore [locate_data_file bug30787_spine.brep] path
|
||||
|
||||
mksweep path
|
||||
addsweep profile
|
||||
|
||||
buildsweep result -C -S
|
Loading…
x
Reference in New Issue
Block a user