mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-09 18:50:54 +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
src
tests/bugs/modalg_7
@ -55,6 +55,8 @@ static Standard_Boolean findNearestValidPoint(
|
|||||||
//
|
//
|
||||||
// the general step is computed using general curve resolution
|
// the general step is computed using general curve resolution
|
||||||
Standard_Real aStep = theCurve.Resolution(theTol) * 1.01;
|
Standard_Real aStep = theCurve.Resolution(theTol) * 1.01;
|
||||||
|
if (aStep < theEps)
|
||||||
|
aStep = theEps;
|
||||||
// aD1Mag is a threshold to consider local derivative magnitude too small
|
// aD1Mag is a threshold to consider local derivative magnitude too small
|
||||||
// and to accelerate going out of sphere
|
// and to accelerate going out of sphere
|
||||||
// (inverse of resolution is the maximal derivative);
|
// (inverse of resolution is the maximal derivative);
|
||||||
@ -159,11 +161,19 @@ Standard_Boolean BRepLib::FindValidRange
|
|||||||
if (theParV2 - theParV1 < Precision::PConfusion())
|
if (theParV2 - theParV1 < Precision::PConfusion())
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
|
|
||||||
Standard_Real anEps = Max(Max(theCurve.Resolution(theTolE) * 0.1,
|
Standard_Boolean isInfParV1 = Precision::IsInfinite (theParV1),
|
||||||
Epsilon(Max(Abs(theParV1), Abs(theParV2)))),
|
isInfParV2 = Precision::IsInfinite (theParV2);
|
||||||
|
|
||||||
|
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());
|
Precision::PConfusion());
|
||||||
|
|
||||||
if (Precision::IsInfinite(theParV1))
|
if (isInfParV1)
|
||||||
theFirst = theParV1;
|
theFirst = theParV1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -174,7 +184,7 @@ Standard_Boolean BRepLib::FindValidRange
|
|||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Precision::IsInfinite(theParV2))
|
if (isInfParV2)
|
||||||
theLast = theParV2;
|
theLast = theParV2;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -304,7 +304,7 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
|
|||||||
{
|
{
|
||||||
Standard_Boolean bIsClosed2;
|
Standard_Boolean bIsClosed2;
|
||||||
Standard_Real aT11, aT12, aT21, aT22;
|
Standard_Real aT11, aT12, aT21, aT22;
|
||||||
Bnd_Box aB2;
|
Bnd_Box aB1, aB2;
|
||||||
//
|
//
|
||||||
bSplit2 = Standard_False;
|
bSplit2 = Standard_False;
|
||||||
myRange1.Range(aT11, aT12);
|
myRange1.Range(aT11, aT12);
|
||||||
@ -313,7 +313,6 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
|
|||||||
bIsClosed2 = IsClosed(myGeom2, aT21, aT22, myTol2, myRes2);
|
bIsClosed2 = IsClosed(myGeom2, aT21, aT22, myTol2, myRes2);
|
||||||
//
|
//
|
||||||
if (bIsClosed2) {
|
if (bIsClosed2) {
|
||||||
Bnd_Box aB1;
|
|
||||||
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
|
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
|
||||||
//
|
//
|
||||||
gp_Pnt aP = myGeom2->Value(aT21);
|
gp_Pnt aP = myGeom2->Value(aT21);
|
||||||
@ -321,8 +320,9 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
|
|||||||
}
|
}
|
||||||
//
|
//
|
||||||
if (!bIsClosed2) {
|
if (!bIsClosed2) {
|
||||||
|
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
|
||||||
BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
|
BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
|
||||||
FindSolutions(myRange1, myRange2, aB2, theRanges1, theRanges2);
|
FindSolutions(myRange1, aB1, myRange2, aB2, theRanges1, theRanges2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@ -343,10 +343,11 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
|
|||||||
//
|
//
|
||||||
for (i = 1; i <= aNb1; ++i) {
|
for (i = 1; i <= aNb1; ++i) {
|
||||||
const IntTools_Range& aR1 = aSegments1(i);
|
const IntTools_Range& aR1 = aSegments1(i);
|
||||||
|
BndBuildBox(myCurve1, aR1.First(), aR1.Last(), myTol1, aB1);
|
||||||
for (j = 1; j <= aNb2; ++j) {
|
for (j = 1; j <= aNb2; ++j) {
|
||||||
const IntTools_Range& aR2 = aSegments2(j);
|
const IntTools_Range& aR2 = aSegments2(j);
|
||||||
BndBuildBox(myCurve2, aR2.First(), aR2.Last(), myTol2, aB2);
|
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 :
|
//purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
|
void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
|
||||||
|
const Bnd_Box& theBox1,
|
||||||
const IntTools_Range& theR2,
|
const IntTools_Range& theR2,
|
||||||
const Bnd_Box& theBox2,
|
const Bnd_Box& theBox2,
|
||||||
IntTools_SequenceOfRanges& theRanges1,
|
IntTools_SequenceOfRanges& theRanges1,
|
||||||
@ -373,6 +375,7 @@ 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 = theBox1;
|
||||||
aB2 = theBox2;
|
aB2 = theBox2;
|
||||||
//
|
//
|
||||||
bThin = Standard_False;
|
bThin = Standard_False;
|
||||||
@ -385,9 +388,7 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
|
|||||||
aTB21 = aT21;
|
aTB21 = aT21;
|
||||||
aTB22 = aT22;
|
aTB22 = aT22;
|
||||||
//
|
//
|
||||||
//1. Build box for first edge and find parameters
|
//1. Find parameters of the second edge in the box of first one
|
||||||
// of the second one in that box
|
|
||||||
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
|
|
||||||
bOut = aB1.IsOut(aB2);
|
bOut = aB1.IsOut(aB2);
|
||||||
if (bOut) {
|
if (bOut) {
|
||||||
break;
|
break;
|
||||||
@ -435,7 +436,9 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
|
|||||||
((aT21 - aTB21) < aSmallStep2) && ((aTB22 - aT22) < aSmallStep2)) {
|
((aT21 - aTB21) < aSmallStep2) && ((aTB22 - aT22) < aSmallStep2)) {
|
||||||
bStop = Standard_True;
|
bStop = Standard_True;
|
||||||
}
|
}
|
||||||
//
|
else
|
||||||
|
BndBuildBox (myCurve1, aT11, aT12, myTol1, aB1);
|
||||||
|
|
||||||
} while (!bStop);
|
} while (!bStop);
|
||||||
//
|
//
|
||||||
if (bOut) {
|
if (bOut) {
|
||||||
@ -498,13 +501,20 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
|
|||||||
Standard_Integer i, aNb1;
|
Standard_Integer i, aNb1;
|
||||||
IntTools_SequenceOfRanges aSegments1;
|
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);
|
IntTools_Range aR2(aT21, aT22);
|
||||||
BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
|
BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
|
||||||
//
|
//
|
||||||
aNb1 = SplitRangeOnSegments(aT11, aT12, myRes1, 3, aSegments1);
|
aNb1 = SplitRangeOnSegments(aT11, aT12, myRes1, 3, aSegments1);
|
||||||
for (i = 1; i <= aNb1; ++i) {
|
for (i = 1; i <= aNb1; ++i) {
|
||||||
const IntTools_Range& aR1 = aSegments1(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
|
//! 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,
|
const IntTools_Range& theR2, const Bnd_Box& theBox2,
|
||||||
IntTools_SequenceOfRanges& theRanges1, IntTools_SequenceOfRanges& theRanges2);
|
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