1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0028553: Incorrect result of the ShapeUpgrade_ShapeDivideContinuity algorithm

The cause of the bug was computation of incorrect UVBounds in the method ShapeAnalysis::GetFaceUVBounds. In this patch the computation of a box for a 2D curve in the method ShapeAnalysis_Curve::FillBndBox() has been improved taking into account intervals of C2 continuity.
Also the fix makes little extension of bounds when making the new surface in ShapeUpgrade_FaceDivide::SplitSurface(), so that all p-curves were fully inside.

Test case for issue CR28553
This commit is contained in:
msv
2017-03-14 17:33:46 +03:00
committed by bugmaster
parent 1b9f3f674e
commit 19e7092d1b
3 changed files with 93 additions and 22 deletions

View File

@@ -637,7 +637,8 @@ static Standard_Integer SearchForExtremum (const Handle(Geom2d_Curve)& C2d,
gp_Pnt2d &res)
{
Standard_Real prevpar;
for ( Standard_Integer i=0; i <10; i++ ) {
Standard_Integer nbOut = 0;
for (Standard_Integer i = 0; i <10; i++) {
prevpar = par;
gp_Vec2d D1, D2;
@@ -647,9 +648,19 @@ static Standard_Integer SearchForExtremum (const Handle(Geom2d_Curve)& C2d,
par -= ( D1 * dir ) / Det;
if ( Abs ( par - prevpar ) < Precision::PConfusion() ) return Standard_True;
if ( First - par >= Precision::PConfusion() ||
par - Last >= Precision::PConfusion() ) return Standard_False;
if (par < First)
{
if (nbOut++ > 2 || prevpar == First)
return Standard_False;
par = First;
}
if (par > Last)
{
if (nbOut++ > 2 || prevpar == Last)
return Standard_False;
par = Last;
}
}
return Standard_True;
}
@@ -661,24 +672,46 @@ void ShapeAnalysis_Curve::FillBndBox (const Handle(Geom2d_Curve)& C2d,
const Standard_Boolean Exact,
Bnd_Box2d &Box) const
{
Standard_Integer nseg = ( NPoints <2 ? 1 : NPoints-1 );
Standard_Real step = ( Last - First ) / nseg;
for ( Standard_Integer i=0; i <= nseg; i++ ) {
Standard_Real par = First + i * step;
gp_Pnt2d pnt = C2d->Value ( par );
Box.Add ( pnt );
if ( ! Exact ) continue;
gp_Pnt2d pextr;
Standard_Real parextr = par;
if ( SearchForExtremum ( C2d, Max(First,par-2.*step), Min(Last,par+2.*step),
gp_Vec2d(1,0), parextr, pextr ) ) {
Box.Add ( pextr );
if (!Exact) {
Standard_Integer nseg = (NPoints < 2 ? 1 : NPoints - 1);
Standard_Real step = (Last - First) / nseg;
for (Standard_Integer i = 0; i <= nseg; i++) {
Standard_Real par = First + i * step;
gp_Pnt2d pnt = C2d->Value(par);
Box.Add(pnt);
}
parextr = par;
if ( SearchForExtremum ( C2d, Max(First,par-2.*step), Min(Last,par+2.*step),
gp_Vec2d(0,1), parextr, pextr ) ) {
Box.Add ( pextr );
return;
}
// We should solve the task on intervals of C2 continuity.
Geom2dAdaptor_Curve anAC(C2d, First, Last);
Standard_Integer nbInt = anAC.NbIntervals(GeomAbs_C2);
// If we have only 1 interval then use input NPoints parameter to get samples.
Standard_Integer nbSamples = (nbInt < 2 ? NPoints - 1 : nbInt);
TColStd_Array1OfReal aParams(1, nbSamples + 1);
if (nbSamples == nbInt)
anAC.Intervals(aParams, GeomAbs_C2);
else {
Standard_Real step = (Last - First) / nbSamples;
for (Standard_Integer i = 0; i <= nbSamples; i++)
aParams(i+1) = First + i * step;
}
for (Standard_Integer i = 1; i <= nbSamples + 1; i++) {
Standard_Real aPar1 = aParams(i);
gp_Pnt2d aPnt = C2d->Value(aPar1);
Box.Add(aPnt);
if (i <= nbSamples) {
Standard_Real aPar2 = aParams(i + 1);
Standard_Real par = (aPar1 + aPar2) * 0.5;
gp_Pnt2d pextr;
Standard_Real parextr = par;
if (SearchForExtremum(C2d, aPar1, aPar2, gp_Vec2d(1, 0), parextr, pextr)) {
Box.Add(pextr);
}
parextr = par;
if (SearchForExtremum(C2d, aPar1, aPar2, gp_Vec2d(0, 1), parextr, pextr)) {
Box.Add(pextr);
}
}
}
}