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

0024055: Reading a STEP file produces invalid shape

Add checks for cone-like surfaces during seam fixing
Delete check for missing degenerated edge for cones in FixMissingSeam() function, because this check is exist in FixPeriodicDegenerated(). Check for uniqueness of wire is unnecessary after this.
Update of test-cases
This commit is contained in:
ika
2014-05-29 16:43:38 +04:00
committed by apn
parent 8696d65d2c
commit 16c7b64236
5 changed files with 63 additions and 33 deletions

View File

@@ -1584,31 +1584,63 @@ Standard_Boolean ShapeFix_Face::FixMissingSeam()
BRep_Builder B;
if ( w1.IsNull() ) return Standard_False;
else if ( w2.IsNull() ) {
// WARNING!!! Temporarily for spheres only:
// If only one of wires limiting face on sphere is open in 2d,
// this means that degenerated edge should be added to one of poles, and
else if ( w2.IsNull()) {
// For spheres and BSpline cone-like surfaces(bug 24055):
// If only one of wires limiting face on surface is open in 2d,
// this may means that degenerated edge should be added, and
// then usual procedure applied
gp_Pnt2d p;
gp_Dir2d d;
Standard_Real aRange;
if ( ismodeu && mySurf->Surface()->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
gp_Pnt2d p ( ( ismodeu < 0 ? 0. : 2.*M_PI ), ismodeu * 0.5 * M_PI );
gp_Dir2d d ( -ismodeu, 0. );
Handle(Geom2d_Line) line = new Geom2d_Line ( p, d );
TopoDS_Edge edge;
B.MakeEdge ( edge );
B.Degenerated ( edge, Standard_True );
B.UpdateEdge ( edge, line, myFace, ::Precision::Confusion() );
B.Range ( edge, myFace, 0., 2*M_PI );
TopoDS_Vertex V;
B.MakeVertex ( V, mySurf->Value ( p.X(), p.Y() ), ::Precision::Confusion() );
V.Orientation(TopAbs_FORWARD);
B.Add(edge,V);
V.Orientation(TopAbs_REVERSED);
B.Add(edge,V);
B.MakeWire ( w2 );
B.Add ( w2, edge );
ws.Append ( w2 );
p.SetCoord ( ( ismodeu < 0 ? 0. : 2.*M_PI ), ismodeu * 0.5 * M_PI );
Standard_Real aXCoord = -ismodeu;
d.SetCoord ( aXCoord, 0.);
aRange = 2.*M_PI;
}
else if ( ismodev && mySurf->Surface()->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
Standard_Real uCoord;
if (mySurf->Value(SUF, SVF).Distance(mySurf->Value(SUF, (SVF + SVL) / 2)) < ::Precision::Confusion())
uCoord = SUF;
else if (mySurf->Value(SUL, SVF).Distance(mySurf->Value(SUL, (SVF + SVL) / 2)) < ::Precision::Confusion())
uCoord = SUL;
else return Standard_False;
p.SetCoord ( uCoord, ( ismodev < 0 ? 0. : VRange ) );
d.SetCoord ( 0., -ismodev);
aRange = VRange;
}
else if ( ismodeu && mySurf->Surface()->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
Standard_Real vCoord;
if (mySurf->Value(SUF, SVF).Distance(mySurf->Value((SUF + SUL) / 2, SVF)) < ::Precision::Confusion())
vCoord = SVF;
else if (mySurf->Value(SUL, SVL).Distance(mySurf->Value((SUF + SUL) / 2, SVL)) < ::Precision::Confusion())
vCoord = SVL;
else return Standard_False;
p.SetCoord ( ( ismodeu < 0 ? 0. : URange ), vCoord );
Standard_Real aXCoord = -ismodeu;
d.SetCoord ( aXCoord, 0.);
aRange = URange;
}
else return Standard_False;
Handle(Geom2d_Line) line = new Geom2d_Line ( p, d );
TopoDS_Edge edge;
B.MakeEdge ( edge );
B.Degenerated ( edge, Standard_True );
B.UpdateEdge ( edge, line, myFace, ::Precision::Confusion() );
B.Range ( edge, myFace, 0., aRange );
TopoDS_Vertex V;
B.MakeVertex ( V, mySurf->Value ( p.X(), p.Y() ), ::Precision::Confusion() );
V.Orientation(TopAbs_FORWARD);
B.Add(edge,V);
V.Orientation(TopAbs_REVERSED);
B.Add(edge,V);
B.MakeWire ( w2 );
B.Add ( w2, edge );
ws.Append ( w2 );
}
// sort original wires
@@ -1724,7 +1756,7 @@ Standard_Boolean ShapeFix_Face::FixMissingSeam()
}
Standard_Boolean skipV = ! vclosed;
if ( vclosed && ! ismodeu ) {
pos1.SetY ( pos1.Y() + ShapeAnalysis::AdjustByPeriod ( pos1.Y(), SVF, URange ) );
pos1.SetY ( pos1.Y() + ShapeAnalysis::AdjustByPeriod ( pos1.Y(), SVF, VRange ) );
if ( foundV ==2 && Abs ( pos1.Y() ) > Abs(vf) ) skipV = Standard_True;
else if ( ! foundV || ( foundV ==1 && Abs ( pos1.Y() ) < Abs(vf) ) ) {
foundV = 1;