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

0025406: BRepOffset_MakeOffset algorithm fails on the face with two degenerated edges on u-iso null curves

Test cases for issue CR25406
This commit is contained in:
jgv
2014-10-23 15:31:47 +04:00
committed by bugmaster
parent 09c597c998
commit 903f7584b8
4 changed files with 515 additions and 734 deletions

View File

@@ -557,8 +557,12 @@ void BRepOffset_Offset::Init(const TopoDS_Face& Face,
BRepOffset::Surface( S, myOffset, myStatus);
//processing offsets of faces with possible degenerated edges
Standard_Boolean UminDegen = Standard_False;
Standard_Boolean UmaxDegen = Standard_False;
Standard_Boolean VminDegen = Standard_False;
Standard_Boolean VmaxDegen = Standard_False;
Standard_Boolean UisoDegen = Standard_False;
Standard_Boolean VisoDegen = Standard_False;
gp_Pnt MinApex, MaxApex;
Standard_Boolean HasSingularity = Standard_False;
Standard_Real uf1, uf2, vf1, vf2, fpar, lpar;
@@ -578,20 +582,41 @@ void BRepOffset_Offset::Init(const TopoDS_Face& Face,
if (!DegEdges.IsEmpty())
{
const Standard_Real TolApex = 1.e-5;
//define the iso of singularity (u or v)
const TopoDS_Edge& theDegEdge = TopoDS::Edge(DegEdges(1));
Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(theDegEdge, Face, fpar, lpar);
gp_Pnt2d fp2d = aCurve->Value(fpar);
gp_Pnt2d lp2d = aCurve->Value(lpar);
if (Abs(fp2d.X() - lp2d.X()) <= Precision::PConfusion())
UisoDegen = Standard_True;
else
VisoDegen = Standard_True;
if (DegEdges.Length() == 2)
{
VminDegen = Standard_True;
VmaxDegen = Standard_True;
if (UisoDegen)
{ UminDegen = Standard_True; UmaxDegen = Standard_True; }
else
{ VminDegen = Standard_True; VmaxDegen = Standard_True; }
}
else //DegEdges.Length() == 1
{
const TopoDS_Edge& theDegEdge = TopoDS::Edge(DegEdges(1));
Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(theDegEdge, Face, fpar, lpar);
gp_Pnt2d aPnt2d = aCurve->Value(fpar);
if (Abs(aPnt2d.Y() - vf1) <= Precision::Confusion())
VminDegen = Standard_True;
else
VmaxDegen = Standard_True;
if (UisoDegen)
{
if (Abs(fp2d.X() - uf1) <= Precision::Confusion())
UminDegen = Standard_True;
else
UmaxDegen = Standard_True;
}
else
{
if (Abs(fp2d.Y() - vf1) <= Precision::Confusion())
VminDegen = Standard_True;
else
VmaxDegen = Standard_True;
}
}
if (TheSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
{
@@ -614,88 +639,166 @@ void BRepOffset_Offset::Init(const TopoDS_Face& Face,
}
else //TheSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)
{
if (UminDegen)
{
Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
if (BRepOffset_Tool::Gabarit( uiso ) > TolApex)
{
Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface();
gp_Pnt Papex, Pfirst, Pquart, Pmid;
Papex = BasisSurf->Value( uf1, vf1 );
Pfirst = TheSurf->Value( uf1, vf1 );
Pquart = TheSurf->Value( uf1, 0.75*vf1+0.25*vf2 );
Pmid = TheSurf->Value( uf1, 0.5*(vf1+vf2) );
gp_Vec DirApex = gp_Vec(Pfirst,Pquart) ^ gp_Vec(Pfirst,Pmid);
Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf1, 1, 0 );
Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
gp_Pnt Pint1, Pint2;
theExtrema.NearestPoints(Pint1, Pint2);
Standard_Real length = Pfirst.Distance(Pint1);
if (OffsetOutside)
{
TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
GeomLib::ExtendSurfByLength(*((Handle(Geom_BoundedSurface)*)&TheSurf), length, 1,
Standard_True, Standard_False);
Standard_Real u1, u2, v1, v2;
TheSurf->Bounds( u1, u2, v1, v2 );
MinApex = TheSurf->Value( u1, vf1 );
}
else
{
Handle(Geom_Curve) viso = TheSurf->VIso( vf1 );
GeomAPI_ProjectPointOnCurve Projector( Pint1, viso );
Standard_Real NewFirstU = Projector.LowerDistanceParameter();
TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, NewFirstU, uf2, vf1, vf2);
MinApex = TheSurf->Value( NewFirstU, vf1 );
}
HasSingularity = Standard_True;
}
} //end of if (UminDegen)
if (UmaxDegen)
{
Handle(Geom_Curve) uiso = TheSurf->UIso( uf2 );
if (BRepOffset_Tool::Gabarit( uiso ) > TolApex)
{
Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface();
gp_Pnt Papex, Pfirst, Pquart, Pmid;
Papex = BasisSurf->Value( uf2, vf1 );
Pfirst = TheSurf->Value( uf2, vf1 );
Pquart = TheSurf->Value( uf2, 0.75*vf1+0.25*vf2 );
Pmid = TheSurf->Value( uf2, 0.5*(vf1+vf2) );
gp_Vec DirApex = gp_Vec(Pfirst,Pquart) ^ gp_Vec(Pfirst,Pmid);
Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
gp_Vec DirGeneratrix = BasisSurf->DN( uf2, vf1, 1, 0 );
Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
gp_Pnt Pint1, Pint2;
theExtrema.NearestPoints(Pint1, Pint2);
Standard_Real length = Pfirst.Distance(Pint1);
if (OffsetOutside)
{
TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
GeomLib::ExtendSurfByLength(*((Handle(Geom_BoundedSurface)*)&TheSurf), length, 1,
Standard_True, Standard_True);
Standard_Real u1, u2, v1, v2;
TheSurf->Bounds( u1, u2, v1, v2 );
MaxApex = TheSurf->Value( u2, vf1 );
}
else
{
Handle(Geom_Curve) viso = TheSurf->VIso( vf1 );
GeomAPI_ProjectPointOnCurve Projector( Pint1, viso );
Standard_Real NewLastU = Projector.LowerDistanceParameter();
TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, NewLastU, vf1, vf2);
MaxApex = TheSurf->Value( NewLastU, vf1 );
}
HasSingularity = Standard_True;
}
} //end of if (UmaxDegen)
if (VminDegen)
{
Handle(Geom_Curve) viso = TheSurf->VIso( vf1 );
if (BRepOffset_Tool::Gabarit( viso ) > TolApex)
{
Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface();
gp_Pnt Papex, Pfirst, Plast, Pmid;
Papex = BasisSurf->Value( uf1, vf1 );
Pfirst = TheSurf->Value( uf1, vf1 );
Plast = TheSurf->Value( uf2, vf1 );
Pmid = TheSurf->Value( (uf1+uf2)/2., vf1 );
gp_Vec DirApex = gp_Vec(Pfirst,Pmid) ^ gp_Vec(Pfirst,Plast);
Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf1, 0, 1 );
Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
gp_Pnt Pint1, Pint2;
theExtrema.NearestPoints(Pint1, Pint2);
Standard_Real length = Pfirst.Distance(Pint1);
if (OffsetOutside)
{
TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
GeomLib::ExtendSurfByLength(*((Handle(Geom_BoundedSurface)*)&TheSurf), length, 1,
Standard_False, Standard_False);
Standard_Real u1, u2, v1, v2;
TheSurf->Bounds( u1, u2, v1, v2 );
MinApex = TheSurf->Value( uf1, v1 );
}
else
{
Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
GeomAPI_ProjectPointOnCurve Projector( Pint1, uiso );
Standard_Real NewFirstV = Projector.LowerDistanceParameter();
TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, NewFirstV, vf2);
MinApex = TheSurf->Value( uf1, NewFirstV );
//TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1+length, vf2);
//MinApex = TheSurf->Value( uf1, vf1+length );
}
HasSingularity = Standard_True;
}
} //end of if (VminDegen)
{
Handle(Geom_Curve) viso = TheSurf->VIso( vf1 );
if (BRepOffset_Tool::Gabarit( viso ) > TolApex)
{
Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface();
gp_Pnt Papex, Pfirst, Pquart, Pmid;
Papex = BasisSurf->Value( uf1, vf1 );
Pfirst = TheSurf->Value( uf1, vf1 );
Pquart = TheSurf->Value( 0.75*uf1+0.25*uf2, vf1 );
Pmid = TheSurf->Value( 0.5*(uf1+uf2), vf1 );
gp_Vec DirApex = gp_Vec(Pfirst,Pquart) ^ gp_Vec(Pfirst,Pmid);
Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf1, 0, 1 );
Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
gp_Pnt Pint1, Pint2;
theExtrema.NearestPoints(Pint1, Pint2);
Standard_Real length = Pfirst.Distance(Pint1);
if (OffsetOutside)
{
TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
GeomLib::ExtendSurfByLength(*((Handle(Geom_BoundedSurface)*)&TheSurf), length, 1,
Standard_False, Standard_False);
Standard_Real u1, u2, v1, v2;
TheSurf->Bounds( u1, u2, v1, v2 );
MinApex = TheSurf->Value( uf1, v1 );
}
else
{
Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
GeomAPI_ProjectPointOnCurve Projector( Pint1, uiso );
Standard_Real NewFirstV = Projector.LowerDistanceParameter();
TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, NewFirstV, vf2);
MinApex = TheSurf->Value( uf1, NewFirstV );
//TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1+length, vf2);
//MinApex = TheSurf->Value( uf1, vf1+length );
}
HasSingularity = Standard_True;
}
} //end of if (VminDegen)
if (VmaxDegen)
{
Handle(Geom_Curve) viso = TheSurf->VIso( vf2 );
if (BRepOffset_Tool::Gabarit( viso ) > TolApex)
{
Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface();
gp_Pnt Papex, Pfirst, Plast, Pmid;
Papex = BasisSurf->Value( uf1, vf2 );
Pfirst = TheSurf->Value( uf1, vf2 );
Plast = TheSurf->Value( uf2, vf2 );
Pmid = TheSurf->Value( (uf1+uf2)/2., vf2 );
gp_Vec DirApex = gp_Vec(Pfirst,Pmid) ^ gp_Vec(Pfirst,Plast);
Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf2, 0, 1 );
Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
gp_Pnt Pint1, Pint2;
theExtrema.NearestPoints(Pint1, Pint2);
Standard_Real length = Pfirst.Distance(Pint1);
if (OffsetOutside)
{
TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
GeomLib::ExtendSurfByLength(*((Handle(Geom_BoundedSurface)*)&TheSurf), length, 1,
Standard_False, Standard_True);
Standard_Real u1, u2, v1, v2;
TheSurf->Bounds( u1, u2, v1, v2 );
MaxApex = TheSurf->Value( uf1, v2 );
}
else
{
Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
GeomAPI_ProjectPointOnCurve Projector( Pint1, uiso );
Standard_Real NewLastV = Projector.LowerDistanceParameter();
TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, NewLastV);
MaxApex = TheSurf->Value( uf1, NewLastV );
//TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2-length);
//MaxApex = TheSurf->Value( uf1, vf2-length );
}
HasSingularity = Standard_True;
}
} //end of if (VmaxDegen)
{
Handle(Geom_Curve) viso = TheSurf->VIso( vf2 );
if (BRepOffset_Tool::Gabarit( viso ) > TolApex)
{
Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface();
gp_Pnt Papex, Pfirst, Pquart, Pmid;
Papex = BasisSurf->Value( uf1, vf2 );
Pfirst = TheSurf->Value( uf1, vf2 );
Pquart = TheSurf->Value( 0.75*uf1+0.25*uf2, vf2 );
Pmid = TheSurf->Value( 0.5*(uf1+uf2), vf2 );
gp_Vec DirApex = gp_Vec(Pfirst,Pquart) ^ gp_Vec(Pfirst,Pmid);
Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf2, 0, 1 );
Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
gp_Pnt Pint1, Pint2;
theExtrema.NearestPoints(Pint1, Pint2);
Standard_Real length = Pfirst.Distance(Pint1);
if (OffsetOutside)
{
TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
GeomLib::ExtendSurfByLength(*((Handle(Geom_BoundedSurface)*)&TheSurf), length, 1,
Standard_False, Standard_True);
Standard_Real u1, u2, v1, v2;
TheSurf->Bounds( u1, u2, v1, v2 );
MaxApex = TheSurf->Value( uf1, v2 );
}
else
{
Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
GeomAPI_ProjectPointOnCurve Projector( Pint1, uiso );
Standard_Real NewLastV = Projector.LowerDistanceParameter();
TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, NewLastV);
MaxApex = TheSurf->Value( uf1, NewLastV );
//TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2-length);
//MaxApex = TheSurf->Value( uf1, vf2-length );
}
HasSingularity = Standard_True;
}
} //end of if (VmaxDegen)
} //end of else (case of Geom_OffsetSurface)
} //end of if (!DegEdges.IsEmpty())
} //end of processing offsets of faces with possible degenerated edges