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

0028694: IGES reader produces too small edge covered by its vertices

Methods IsUClosed() and IsVClosed() are changed (check distance to middle point is added).
This commit is contained in:
skl 2018-08-09 12:26:20 +03:00 committed by bugmaster
parent 2382618330
commit 65bb82f241
4 changed files with 901 additions and 727 deletions

View File

@ -533,125 +533,214 @@ Handle(Geom_Curve) ShapeAnalysis_Surface::VIso(const Standard_Real V)
Standard_Boolean ShapeAnalysis_Surface::IsUClosed(const Standard_Real preci)
{
Standard_Real prec = Max(preci, Precision::Confusion());
if (myUCloseVal < 0) {
Standard_Real anUmidVal = -1.;
if (myUCloseVal < 0)
{
// Faut calculer : calculs minimaux
Standard_Real uf, ul, vf, vl;
Bounds(uf, ul, vf, vl);//modified by rln on 12/11/97 mySurf-> is deleted
//mySurf->Bounds (uf,ul,vf,vl);
if (Precision::IsInfinite (uf) || Precision::IsInfinite (ul)) myUDelt = 0.;
else myUDelt = Abs (ul-uf) / 20;//modified by rln 11/11/97 instead of 10
if (Precision::IsInfinite(uf) || Precision::IsInfinite(ul))
{
myUDelt = 0.;
}
else
{
myUDelt = Abs(ul - uf) / 20;//modified by rln 11/11/97 instead of 10
//because of the example when 10 was not enough
if (mySurf->IsUClosed()) { myUCloseVal = 0.; myUDelt = 0.; myGap = 0.; return Standard_True; }
}
if (mySurf->IsUClosed())
{
myUCloseVal = 0.;
myUDelt = 0.;
myGap = 0.;
return Standard_True;
}
//Calculs adaptes
//#67 rln S4135
GeomAdaptor_Surface& SurfAdapt = Adaptor3d()->ChangeSurface();
GeomAbs_SurfaceType surftype = SurfAdapt.GetType();
if (mySurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
{
surftype = GeomAbs_OtherSurface;
}
switch (surftype) {
case GeomAbs_Plane: {
switch (surftype)
{
case GeomAbs_Plane:
{
myUCloseVal = RealLast();
break;
}
case GeomAbs_SurfaceOfExtrusion: { //:c8 abv 03 Mar 98: UKI60094 #753: process Geom_SurfaceOfLinearExtrusion
case GeomAbs_SurfaceOfExtrusion:
{ //:c8 abv 03 Mar 98: UKI60094 #753: process Geom_SurfaceOfLinearExtrusion
Handle(Geom_SurfaceOfLinearExtrusion) extr =
Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(mySurf);
Handle(Geom_Curve) crv = extr->BasisCurve();
Standard_Real f = crv->FirstParameter();
Standard_Real l = crv->LastParameter();
//:r3 abv (smh) 30 Mar 99: protect against unexpected signals
if ( ! Precision::IsInfinite ( f ) && ! Precision::IsInfinite ( l ) ) {
if (!Precision::IsInfinite(f) && !Precision::IsInfinite(l))
{
gp_Pnt p1 = crv->Value(f);
gp_Pnt p2 = crv->Value(l);
myUCloseVal = p1.Distance ( p2 );
myUCloseVal = p1.SquareDistance(p2);
gp_Pnt pm = crv->Value((f + l) / 2.);
anUmidVal = p1.SquareDistance(pm);
}
else
{
myUCloseVal = RealLast();
}
else myUCloseVal = RealLast();
break;
}
case GeomAbs_BSplineSurface: {
case GeomAbs_BSplineSurface:
{
Handle(Geom_BSplineSurface) bs = Handle(Geom_BSplineSurface)::DownCast(mySurf);
Standard_Integer nbup = bs->NbUPoles();
Standard_Real distmin = RealLast();
if (bs->IsUPeriodic()) {
if (bs->IsUPeriodic())
{
myUCloseVal = 0;
myUDelt = 0;
}
else if (nbup < 3) {//modified by rln on 12/11/97
else if (nbup < 3)
{//modified by rln on 12/11/97
myUCloseVal = RealLast();
}
else if (bs->IsURational() ||
//#6 rln 20/02/98 ProSTEP ug_exhaust-A.stp entity #18360 (Uclosed BSpline,
//but multiplicity of boundary knots != degree + 1)
bs->UMultiplicity(1) != bs->UDegree() + 1 || //#6 //:h4: #6 moved
bs->UMultiplicity(bs->NbUKnots()) != bs->UDegree()+1 ) { //#6 //:h4
bs->UMultiplicity(bs->NbUKnots()) != bs->UDegree() + 1)
{ //#6 //:h4
Standard_Integer nbvk = bs->NbVKnots();
for (Standard_Integer i = 1; i <= nbvk; i ++) {
Standard_Real v = bs->VKnot(i);
Standard_Real v = bs->VKnot(1);
gp_Pnt p1 = SurfAdapt.Value(uf, v);
gp_Pnt p2 = SurfAdapt.Value(ul, v);
myUCloseVal = Max (myUCloseVal, p1.SquareDistance (p2));
distmin = Min (distmin, p1.SquareDistance (p2));
if (i > 1) {
myUCloseVal = p1.SquareDistance(p2);
gp_Pnt pm = SurfAdapt.Value((uf + ul) / 2., v);
anUmidVal = p1.SquareDistance(pm);
distmin = myUCloseVal;
for (Standard_Integer i = 2; i <= nbvk; i++)
{
v = 0.5 * (bs->VKnot(i - 1) + bs->VKnot(i));
p1 = bs->Value(uf, v);
p2 = bs->Value(ul, v);
myUCloseVal = Max (myUCloseVal, p1.SquareDistance (p2));
distmin = Min (distmin, p1.SquareDistance (p2));
Standard_Real aDist = p1.SquareDistance(p2);
if (aDist > myUCloseVal)
{
myUCloseVal = aDist;
pm = bs->Value((uf + ul) / 2., v);
anUmidVal = p1.SquareDistance(pm);
}
else
{
distmin = Min(distmin, aDist);
}
}
myUCloseVal = Sqrt (myUCloseVal);
distmin = Sqrt(distmin);
myUDelt = Min(myUDelt, 0.5 * SurfAdapt.UResolution(distmin)); //#4 smh
}
else {
else
{
Standard_Integer nbvp = bs->NbVPoles();
for (Standard_Integer i = 1; i <= nbvp; i ++) {
myUCloseVal = Max (myUCloseVal, bs->Pole(1,i).SquareDistance(bs->Pole(nbup,i)));
distmin = Min (distmin, bs->Pole(1,i).SquareDistance(bs->Pole(nbup,i)));
myUCloseVal = bs->Pole(1, 1).SquareDistance(bs->Pole(nbup, 1));
anUmidVal = bs->Pole(1, 1).SquareDistance(bs->Pole(nbup / 2 + 1, 1));
distmin = myUCloseVal;
for (Standard_Integer i = 2; i <= nbvp; i++)
{
Standard_Real aDist = bs->Pole(1, i).SquareDistance(bs->Pole(nbup, i));
if (aDist > myUCloseVal)
{
myUCloseVal = aDist;
anUmidVal = bs->Pole(1, i).SquareDistance(bs->Pole(nbup / 2 + 1, i));
}
else
{
distmin = Min(distmin, aDist);
}
}
myUCloseVal = Sqrt (myUCloseVal);
distmin = Sqrt(distmin);
myUDelt = Min(myUDelt, 0.5 * SurfAdapt.UResolution(distmin)); //#4 smh
}
break;
}
case GeomAbs_BezierSurface: {
case GeomAbs_BezierSurface:
{
Handle(Geom_BezierSurface) bz = Handle(Geom_BezierSurface)::DownCast(mySurf);
Standard_Integer nbup = bz->NbUPoles();
Standard_Real distmin = RealLast();
if (nbup < 3)
{
myUCloseVal = RealLast();
else {
Standard_Integer nbvp = bz->NbVPoles();
for (Standard_Integer i = 1; i <= nbvp; i ++) {
myUCloseVal = Max (myUCloseVal, bz->Pole(1,i).SquareDistance(bz->Pole(nbup,i)));
distmin = Min (distmin, bz->Pole(1,i).SquareDistance(bz->Pole(nbup,i)));
}
myUCloseVal = Sqrt (myUCloseVal);
else
{
Standard_Integer nbvp = bz->NbVPoles();
myUCloseVal = bz->Pole(1, 1).SquareDistance(bz->Pole(nbup, 1));
anUmidVal = bz->Pole(1, 1).SquareDistance(bz->Pole(nbup / 2 + 1, 1));
distmin = myUCloseVal;
for (Standard_Integer i = 1; i <= nbvp; i++)
{
Standard_Real aDist = bz->Pole(1, i).SquareDistance(bz->Pole(nbup, i));
if (aDist > myUCloseVal) {
myUCloseVal = aDist;
anUmidVal = bz->Pole(1, i).SquareDistance(bz->Pole(nbup / 2 + 1, i));
}
else
{
distmin = Min(distmin, aDist);
}
}
distmin = Sqrt(distmin);
myUDelt = Min(myUDelt, 0.5 * SurfAdapt.UResolution(distmin)); //#4 smh
}
break;
}
default: { //Geom_RectangularTrimmedSurface and Geom_OffsetSurface
default:
{ //Geom_RectangularTrimmedSurface and Geom_OffsetSurface
Standard_Real distmin = RealLast();
Standard_Integer nbpoints = 101; //can be revised
for (Standard_Integer i = 0; i < nbpoints; i++) {
gp_Pnt p1 = SurfAdapt.Value (uf, vf + (vl - vf ) * i / (nbpoints - 1));
gp_Pnt p2 = SurfAdapt.Value (ul, vf + (vl - vf ) * i / (nbpoints - 1));
myUCloseVal = Max (myUCloseVal, p1.SquareDistance (p2));
distmin = Min (distmin, p1.SquareDistance (p2));
gp_Pnt p1 = SurfAdapt.Value(uf, vf);
gp_Pnt p2 = SurfAdapt.Value(ul, vf);
myUCloseVal = p1.SquareDistance(p2);
gp_Pnt pm = SurfAdapt.Value((uf + ul) / 2, vf);
anUmidVal = p1.SquareDistance(pm);
distmin = myUCloseVal;
for (Standard_Integer i = 1; i < nbpoints; i++)
{
Standard_Real vparam = vf + (vl - vf) * i / (nbpoints - 1);
p1 = SurfAdapt.Value(uf, vparam);
p2 = SurfAdapt.Value(ul, vparam);
Standard_Real aDist = p1.SquareDistance(p2);
if (aDist > myUCloseVal)
{
myUCloseVal = aDist;
pm = SurfAdapt.Value((uf + ul) / 2, vparam);
anUmidVal = p1.SquareDistance(pm);
}
else
{
distmin = Min(distmin, aDist);
}
}
myUCloseVal = Sqrt (myUCloseVal);
distmin = Sqrt(distmin);
myUDelt = Min(myUDelt, 0.5 * SurfAdapt.UResolution(distmin)); //#4 smh
break;
}
} //switch
myGap = myUCloseVal;
myGap = sqrt(myUCloseVal);
myUCloseVal = myGap;
}
if (anUmidVal > 0. && myUCloseVal > sqrt(anUmidVal))
{
myUCloseVal = RealLast();
return Standard_False;
}
return (myUCloseVal <= prec);
}
@ -663,124 +752,209 @@ Standard_Boolean ShapeAnalysis_Surface::IsUClosed(const Standard_Real preci)
Standard_Boolean ShapeAnalysis_Surface::IsVClosed(const Standard_Real preci)
{
Standard_Real prec = Max(preci, Precision::Confusion());
if (myVCloseVal < 0) {
Standard_Real aVmidVal = -1.;
if (myVCloseVal < 0)
{
// Faut calculer : calculs minimaux
Standard_Real uf, ul, vf, vl;
Bounds(uf, ul, vf, vl);//modified by rln on 12/11/97 mySurf-> is deleted
// mySurf->Bounds (uf,ul,vf,vl);
if (Precision::IsInfinite (vf) || Precision::IsInfinite (vl)) myVDelt = 0.;
else myVDelt = Abs (vl-vf) / 20;// 2; rln S4135
if (Precision::IsInfinite(vf) || Precision::IsInfinite(vl))
{
myVDelt = 0.;
}
else
{
myVDelt = Abs(vl - vf) / 20;// 2; rln S4135
//because of the example when 10 was not enough
if (mySurf->IsVClosed()) { myVCloseVal = 0.; myVDelt = 0.; myGap = 0.; return Standard_True; }
}
if (mySurf->IsVClosed())
{
myVCloseVal = 0.;
myVDelt = 0.;
myGap = 0.;
return Standard_True;
}
// Calculs adaptes
//#67 rln S4135
GeomAdaptor_Surface& SurfAdapt = Adaptor3d()->ChangeSurface();
GeomAbs_SurfaceType surftype = SurfAdapt.GetType();
if (mySurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
{
surftype = GeomAbs_OtherSurface;
}
switch (surftype) {
switch (surftype)
{
case GeomAbs_Plane:
case GeomAbs_Cone:
case GeomAbs_Cylinder:
case GeomAbs_Sphere:
case GeomAbs_SurfaceOfExtrusion: {
case GeomAbs_SurfaceOfExtrusion:
{
myVCloseVal = RealLast();
break;
}
case GeomAbs_SurfaceOfRevolution: {
case GeomAbs_SurfaceOfRevolution:
{
Handle(Geom_SurfaceOfRevolution) revol =
Handle(Geom_SurfaceOfRevolution)::DownCast(mySurf);
Handle(Geom_Curve) crv = revol->BasisCurve();
gp_Pnt p1 = crv->Value(crv->FirstParameter());
gp_Pnt p2 = crv->Value(crv->LastParameter());
myVCloseVal = p1.Distance ( p2 );
myVCloseVal = p1.SquareDistance(p2);
break;
}
case GeomAbs_BSplineSurface: {
case GeomAbs_BSplineSurface:
{
Handle(Geom_BSplineSurface) bs = Handle(Geom_BSplineSurface)::DownCast(mySurf);
Standard_Integer nbvp = bs->NbVPoles();
Standard_Real distmin = RealLast();
if (bs->IsVPeriodic()) {
if (bs->IsVPeriodic())
{
myVCloseVal = 0;
myVDelt = 0;
}
else if (nbvp < 3) {//modified by rln on 12/11/97
else if (nbvp < 3)
{//modified by rln on 12/11/97
myVCloseVal = RealLast();
}
else if (bs->IsVRational() ||
bs->VMultiplicity(1) != bs->VDegree() + 1 || //#6 //:h4
bs->VMultiplicity(bs->NbVKnots()) != bs->VDegree()+1 ) { //#6 //:h4
bs->VMultiplicity(bs->NbVKnots()) != bs->VDegree() + 1)
{ //#6 //:h4
Standard_Integer nbuk = bs->NbUKnots();
for (Standard_Integer i = 1; i <= nbuk; i ++) {
Standard_Real u = bs->UKnot(i);
Standard_Real u = bs->UKnot(1);
gp_Pnt p1 = SurfAdapt.Value(u, vf);
gp_Pnt p2 = SurfAdapt.Value(u, vl);
myVCloseVal = Max (myVCloseVal, p1.SquareDistance (p2));
distmin = Min (distmin, p1.SquareDistance (p2));
if (i > 1) {
myVCloseVal = p1.SquareDistance(p2);
gp_Pnt pm = SurfAdapt.Value(u, (vf + vl) / 2.);
aVmidVal = p1.SquareDistance(pm);
distmin = myVCloseVal;
for (Standard_Integer i = 2; i <= nbuk; i++)
{
u = 0.5 * (bs->UKnot(i - 1) + bs->UKnot(i));
p1 = SurfAdapt.Value(u, vf);
p2 = SurfAdapt.Value(u, vl);
myVCloseVal = Max (myVCloseVal, p1.SquareDistance (p2));
distmin = Min (distmin, p1.SquareDistance (p2));
Standard_Real aDist = p1.SquareDistance(p2);
if (aDist > myVCloseVal)
{
myVCloseVal = aDist;
pm = SurfAdapt.Value(u, (vf + vl) / 2);
aVmidVal = p1.SquareDistance(pm);
}
else
{
distmin = Min(distmin, aDist);
}
}
myVCloseVal = Sqrt (myVCloseVal);
distmin = Sqrt(distmin);
myVDelt = Min(myVDelt, 0.5 * SurfAdapt.VResolution(distmin)); //#4 smh
}
else {
else
{
Standard_Integer nbup = bs->NbUPoles();
for (Standard_Integer i = 1; i <= nbup; i ++) {
myVCloseVal = Max (myVCloseVal, bs->Pole(i,1).SquareDistance(bs->Pole(i,nbvp)));
distmin = Min (distmin, bs->Pole(i,1).SquareDistance(bs->Pole(i,nbvp)));
myVCloseVal = bs->Pole(1, 1).SquareDistance(bs->Pole(1, nbvp));
aVmidVal = bs->Pole(1, 1).SquareDistance(bs->Pole(1, nbvp / 2 + 1));
distmin = myVCloseVal;
for (Standard_Integer i = 2; i <= nbup; i++)
{
Standard_Real aDist = bs->Pole(i, 1).SquareDistance(bs->Pole(i, nbvp));
if (aDist > myVCloseVal)
{
myVCloseVal = aDist;
aVmidVal = bs->Pole(i, 1).SquareDistance(bs->Pole(i, nbvp / 2 + 1));
}
else
{
distmin = Min(distmin, aDist);
}
}
myVCloseVal = Sqrt (myVCloseVal);
distmin = Sqrt(distmin);
myVDelt = Min(myVDelt, 0.5 * SurfAdapt.VResolution(distmin)); //#4 smh
}
break;
}
case GeomAbs_BezierSurface: {
case GeomAbs_BezierSurface:
{
Handle(Geom_BezierSurface) bz = Handle(Geom_BezierSurface)::DownCast(mySurf);
Standard_Integer nbvp = bz->NbVPoles();
Standard_Real distmin = RealLast();
if (nbvp < 3)
{
myVCloseVal = RealLast();
else {
Standard_Integer nbup = bz->NbUPoles();
for (Standard_Integer i = 1; i <= nbup; i ++) {
myVCloseVal = Max (myVCloseVal, bz->Pole(i,1).SquareDistance(bz->Pole(i,nbvp)));
distmin = Min (distmin, bz->Pole(i,1).SquareDistance(bz->Pole(i,nbvp)));
}
myVCloseVal = Sqrt (myVCloseVal);
else
{
Standard_Integer nbup = bz->NbUPoles();
myVCloseVal = bz->Pole(1, 1).SquareDistance(bz->Pole(1, nbvp));
aVmidVal = bz->Pole(1, 1).SquareDistance(bz->Pole(1, nbvp / 2 + 1));
distmin = myVCloseVal;
for (Standard_Integer i = 2; i <= nbup; i++)
{
Standard_Real aDist = bz->Pole(i, 1).SquareDistance(bz->Pole(i, nbvp));
if (aDist > myVCloseVal)
{
myVCloseVal = aDist;
aVmidVal = bz->Pole(i, 1).SquareDistance(bz->Pole(i, nbvp / 2 + 1));
}
else
{
distmin = Min(distmin, aDist);
}
}
distmin = Sqrt(distmin);
myVDelt = Min(myVDelt, 0.5 * SurfAdapt.VResolution(distmin)); //#4 smh
}
break;
}
default: { //Geom_RectangularTrimmedSurface and Geom_OffsetSurface
default:
{ //Geom_RectangularTrimmedSurface and Geom_OffsetSurface
Standard_Real distmin = RealLast();
Standard_Integer nbpoints = 101; //can be revised
for (Standard_Integer i = 0; i < nbpoints; i++) {
gp_Pnt p1 = SurfAdapt.Value (uf + (ul - uf ) * i / (nbpoints - 1), vf);
gp_Pnt p2 = SurfAdapt.Value (uf + (ul - uf ) * i / (nbpoints - 1), vl);
myVCloseVal = Max (myVCloseVal, p1.SquareDistance (p2));
distmin = Min (distmin, p1.SquareDistance (p2));
gp_Pnt p1 = SurfAdapt.Value(uf, vf);
gp_Pnt p2 = SurfAdapt.Value(uf, vl);
gp_Pnt pm = SurfAdapt.Value(uf, (vf + vl) / 2);
myVCloseVal = p1.SquareDistance(p2);
aVmidVal = p1.SquareDistance(pm);
distmin = myVCloseVal;
for (Standard_Integer i = 1; i < nbpoints; i++)
{
Standard_Real uparam = uf + (ul - uf) * i / (nbpoints - 1);
p1 = SurfAdapt.Value(uparam, vf);
p2 = SurfAdapt.Value(uparam, vl);
Standard_Real aDist = p1.SquareDistance(p2);
if (aDist > myVCloseVal)
{
myVCloseVal = aDist;
pm = SurfAdapt.Value(uparam, (vf + vl) / 2);
aVmidVal = p1.SquareDistance(pm);
}
else
{
distmin = Min(distmin, aDist);
}
}
myVCloseVal = Sqrt (myVCloseVal);
distmin = Sqrt(distmin);
myVDelt = Min(myVDelt, 0.5 * SurfAdapt.VResolution(distmin)); //#4 smh
break;
}
} //switch
myGap = myVCloseVal;
myGap = Sqrt(myVCloseVal);
myVCloseVal = myGap;
}
if (aVmidVal > 0. && myVCloseVal > sqrt(aVmidVal))
{
myVCloseVal = RealLast();
return Standard_False;
}
return (myVCloseVal <= prec);
}
//=======================================================================
//function : SurfaceNewton
//purpose : Newton algo (S4030)

View File

@ -1918,7 +1918,7 @@ static Standard_Integer IsShortSegment (const ShapeFix_WireSegment &seg,
const Standard_Real VResolution)
{
TopoDS_Vertex Vf = seg.FirstVertex();
if ( ! Vf.IsSame ( seg.LastVertex() ) ) return Standard_False;
if ( ! Vf.IsSame ( seg.LastVertex() ) ) return 0;
gp_Pnt pnt = BRep_Tool::Pnt(Vf);
Standard_Real tol = BRep_Tool::Tolerance(Vf);
@ -1929,7 +1929,7 @@ static Standard_Integer IsShortSegment (const ShapeFix_WireSegment &seg,
Handle(ShapeExtend_WireData) sbwd = seg.WireData();
for ( Standard_Integer i=1; i <= sbwd->NbEdges(); i++ ) {
TopoDS_Edge edge = sbwd->Edge ( i );
if ( ! Vf.IsSame ( sae.LastVertex ( edge ) ) ) return Standard_False;
if ( ! Vf.IsSame ( sae.LastVertex ( edge ) ) ) return 0;
Handle(Geom2d_Curve) c2d;
Standard_Real f, l;
if ( ! sae.PCurve ( edge, myFace, c2d, f, l ) ) continue;

View File

@ -1,5 +1,3 @@
puts "TODO OCC28694 ALL: ERROR: OCC28694 is reproduced."
puts "========"
puts "OCC28694"
puts "========"

View File

@ -1,3 +1,5 @@
puts "TODO bug30075 ALL: Faulty shapes in variables faulty_1 to faulty_"
puts "========================"
puts " OCC55 "
puts "========================"