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

0030082: Intersection algorithm returns curve with big tolerance value

The fix inserts new points at the end of the WLine in case when the direction of the intersection curve is significantly changed.
This commit is contained in:
nbv 2018-08-23 16:37:59 +03:00 committed by bugmaster
parent 4a056d205b
commit 7eb3580b79
3 changed files with 180 additions and 2 deletions

View File

@ -3376,6 +3376,90 @@ static IntPatch_ImpImpIntersection::IntStatus
if (aPf.IsSame(aPl, Precision::Confusion()))
isGood = Standard_False;
}
else if (aWLine[i]->NbPnts() > 2)
{
// Sometimes points of the WLine are distributed
// linearly and uniformly. However, such position
// of the points does not always describe the real intersection
// curve. I.e. real tangents at the ends of the intersection
// curve can significantly deviate from this "line" direction.
// Here we are processing this case by inserting additional points
// to the beginning/end of the WLine to make it more precise.
// See description to the issue #30082.
const Standard_Real aSqTol3D = aTol3D*aTol3D;
for (Standard_Integer j = 0; j < 2; j++)
{
// If j == 0 ==> add point at begin of WLine.
// If j == 1 ==> add point at end of WLine.
for (;;)
{
if (aWLine[i]->NbPnts() >= aNbMaxPoints)
{
break;
}
// Take 1st and 2nd point to compute the "line" direction.
// For our convenience, we make 2nd point be the ends of the WLine
// because it will be used for computation of the normals
// to the surfaces.
const Standard_Integer anIdx1 = j ? aWLine[i]->NbPnts() - 1 : 2;
const Standard_Integer anIdx2 = j ? aWLine[i]->NbPnts() : 1;
const gp_Pnt &aP1 = aWLine[i]->Point(anIdx1).Value();
const gp_Pnt &aP2 = aWLine[i]->Point(anIdx2).Value();
const gp_Vec aDir(aP1, aP2);
if (aDir.SquareMagnitude() < aSqTol3D)
{
break;
}
// Compute tangent in first/last point of the WLine.
// We do not take into account the flag "isReversed"
// because strict direction of the tangent is not
// important here (we are interested in the tangent
// line itself and nothing to fear if its direction
// is reversed).
const gp_Vec aN1 = aQuad1.Normale(aP2);
const gp_Vec aN2 = aQuad2.Normale(aP2);
const gp_Vec aTg(aN1.Crossed(aN2));
if (aTg.SquareMagnitude() < Precision::SquareConfusion())
{
// Tangent zone
break;
}
// Check of the bending
Standard_Real anAngle = aDir.Angle(aTg);
if (anAngle > M_PI_2)
anAngle -= M_PI;
if (Abs(anAngle) > 0.25) // ~ 14deg.
{
const Standard_Integer aNbPntsPrev = aWLine[i]->NbPnts();
SeekAdditionalPoints(aQuad1, aQuad2, aWLine[i]->Curve(),
anEquationCoeffs, i, 3, anIdx1, anIdx2,
aTol2D, aPeriod, isReversed);
if (aWLine[i]->NbPnts() == aNbPntsPrev)
{
// No points have been added. ==> Exit from a loop.
break;
}
}
else
{
// Good result has been achieved. ==> Exit from a loop.
break;
}
} // for (;;)
}
}
if (isGood)
{
@ -3383,8 +3467,8 @@ static IntPatch_ImpImpIntersection::IntStatus
isAddedIntoWL[i] = Standard_True;
SeekAdditionalPoints(aQuad1, aQuad2, aWLine[i]->Curve(),
anEquationCoeffs, i, aNbPoints, 1,
aWLine[i]->NbPnts(), aTol2D, aPeriod,
isReversed);
aWLine[i]->NbPnts(), aTol2D, aPeriod,
isReversed);
aWLine[i]->ComputeVertexParameters(aTol3D);
theSlin.Append(aWLine[i]);

View File

@ -0,0 +1,27 @@
puts "========"
puts "0030082: Intersection algorithm returns curve with big tolerance value"
puts "========"
puts ""
foreach a [directory c_*] { unset $a }
brestore [locate_data_file bug27928_b1.brep] b1
brestore [locate_data_file bug27928_b2.brep] b2
explode b1 f
explode b2 f
if { [regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b1_1 b2_2 -2d] full Toler NbCurv ] } {
# Before the fix, the tolerance was 0.0010828835451753697
checkreal Tolerance $Toler 6.5e-7 0.0 0.1
if {$NbCurv != 1} {
puts "Error: 1 curve is expected but $NbCurv curves are found."
}
} else {
puts "Error: Intersection result is empty"
}
smallview
don c_*
fit
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

View File

@ -0,0 +1,67 @@
puts "========"
puts "0030082: Intersection algorithm returns curve with big tolerance value"
puts "========"
puts ""
foreach a [directory res*] {unset $a}
set aTol 1.0e-4
set GoodNbCurves 4
cylinder s1 -106.471129473161 -64.3442185874231 -19.25 1 0 0 0 0 -1 0.25
cylinder s2 -124.971129473161 -67.0942185874231 -20.5 0 0 1 1 0 -0 3
intersect res s1 s2 $aTol
set che [whatis res]
set ind [string first "3d curve" $che]
if {${ind} >= 0} {
#Only variable "res" exists
renamevar res res_1
}
bclearobjects
bcleartools
set ic 1
set AllowRepeat 1
while { $AllowRepeat != 0 } {
set che [whatis res_$ic]
set ind [string first "3d curve" $che]
if {${ind} < 0} {
set AllowRepeat 0
} else {
bounds res_$ic U1 U2
if {[dval U2-U1] < 1.0e-9} {
puts "Error: Wrong curve's range!"
}
xdistcs res_$ic s1 U1 U2 100 $aTol
xdistcs res_$ic s2 U1 U2 100 $aTol
mkedge ee res_$ic
baddobjects ee
incr ic
}
}
incr ic -1
if { $ic != $GoodNbCurves } {
puts "Error: $GoodNbCurves curves are expected but $ic ones are found"
}
bfillds
bbuild result
smallview
don result
fit
# Check gaps between edges in ce
checksection result -r 0
checkmaxtol result -min_tol 2.0e-7
checknbshapes result -edge 4 -vertex 3
checkview -screenshot -2d -path ${imagedir}/${test_image}.png