1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-08 18:40:55 +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

@ -2154,6 +2154,8 @@ void BRepOffset_MakeOffset::CorrectConicalFaces()
BB.Add( theShell, NewSphericalFace ); BB.Add( theShell, NewSphericalFace );
} }
if (myShape.ShapeType() == TopAbs_SOLID || myThickening)
{
Explo.Init( myOffsetShape, TopAbs_SHELL ); Explo.Init( myOffsetShape, TopAbs_SHELL );
if (Explo.More()) { if (Explo.More()) {
@ -2161,385 +2163,6 @@ void BRepOffset_MakeOffset::CorrectConicalFaces()
theShell.Closed( Standard_True ); theShell.Closed( Standard_True );
} }
/*
//Reconstructing
BRep_Builder BB;
for (i = 1; i <= Cones.Length(); i++)
{
TopoDS_Face Cone = TopoDS::Face( Cones(i) );
TopoDS_Edge Circ = TopoDS::Edge( Circs(i) );
TopoDS_Edge Seam = TopoDS::Edge( Seams(i) );
if (Circ.IsNull()) //case 1 with big offset
{
//ExtraFace is absent
Handle(Geom_Surface) aSurf = BRep_Tool::Surface( Cone ), OffSurf = aSurf;
if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
gp_Pnt apex = theCone.Apex();
Standard_Real Uapex, Vapex;
ElSLib::Parameters( theCone, apex, Uapex, Vapex );
if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
apex = OffSurf->Value( Uapex, Vapex );
//Making new degenerated edge
Handle(Geom2d_Line) theLine = GCE2d_MakeLine( gp_Pnt2d( 0., Vapex ), gp_Pnt2d( 2.*M_PI, Vapex ) );
TopoDS_Edge NewEdge;
BB.MakeEdge( NewEdge );
NewEdge.Orientation(TopAbs_FORWARD);
BB.UpdateEdge( NewEdge, theLine, Cone, Precision::Confusion() );
BB.Range( NewEdge, 0., 2.*M_PI );
BB.SameParameter( NewEdge, Standard_True );
BB.SameRange( NewEdge, Standard_True );
BB.Degenerated( NewEdge, Standard_True );
TopoDS_Vertex Apex = BRepLib_MakeVertex( apex );
BB.Add( NewEdge, Apex.Oriented(TopAbs_FORWARD) );
BB.Add( NewEdge, Apex.Oriented(TopAbs_REVERSED) );
//Reconstructing Seam
Standard_Real f, l, par, cpar;
Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( Seam, Cone, f, l );
gp_Lin2d aLine = (Handle(Geom2d_Line)::DownCast(theCurve))->Lin2d();
par = ElCLib::Parameter( aLine, gp_Pnt2d( Uapex, Vapex ) );
TopoDS_Shape aLocalShape = Seam.Oriented(TopAbs_FORWARD);
TopoDS_Vertex cver = TopExp::LastVertex( TopoDS::Edge(aLocalShape) );
cpar = BRep_Tool::Parameter( cver, Seam, Cone );
if (Abs(f-cpar) < Abs(l-cpar))
BB.Range( Seam, par, l );
else
BB.Range( Seam, f, par );
Seam.Free( Standard_True );
TopoDS_Shape cver1;
TopoDS_Iterator iter( Seam );
for (; iter.More(); iter.Next())
{
cver1 = iter.Value();
if (cver1.IsSame(cver))
break;
}
BB.Remove( Seam, cver1 );
if (Abs(f-cpar) < Abs(l-cpar))
BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_FORWARD) ) );
else
BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_REVERSED) ) );
//Adding NewEdge into Cone
TopoDS_Shape theWire;
for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
{
theWire = fexp.Current();
Standard_Boolean found = Standard_False;
for (iter.Initialize( theWire ); iter.More(); iter.Next())
{
if (Seam.IsSame( iter.Value() ))
{
found = Standard_True;
break;
}
}
if (found)
break;
}
theWire.Free( Standard_True );
NewEdge.Orientation( TopAbs::Compose(theWire.Orientation(),TopAbs_REVERSED) );
BB.Add( theWire, NewEdge );
} //end of case 1 with big offset
else
{
Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Circ.TShape());
if (! TE->Degenerated()) //case 1
{
//Find ExtraFace
TopoDS_Face ExtraFace;
for (fexp.Init( myOffsetShape, TopAbs_FACE ); fexp.More(); fexp.Next())
{
ExtraFace = TopoDS::Face( fexp.Current() );
if (ExtraFace.IsSame( Cone ))
continue;
Standard_Boolean found = Standard_False;
TopExp_Explorer eexp( ExtraFace, TopAbs_EDGE );
for (; eexp.More(); eexp.Next())
if (Circ.IsSame( eexp.Current() ))
{
found = Standard_True;
break;
}
if (found)
break;
}
Handle(Geom_Surface) aSurf = BRep_Tool::Surface( Cone ), OffSurf = aSurf;
if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
gp_Pnt apex = theCone.Apex();
Standard_Real Uapex, Vapex;
ElSLib::Parameters( theCone, apex, Uapex, Vapex );
if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
apex = OffSurf->Value( Uapex, Vapex );
//Making new degenerated edge
Handle(Geom2d_Line) theLine = GCE2d_MakeLine( gp_Pnt2d( 0., Vapex ), gp_Pnt2d( 2.*M_PI, Vapex ) );
TopoDS_Edge NewEdge;
BB.MakeEdge( NewEdge );
NewEdge.Orientation(TopAbs_FORWARD);
BB.UpdateEdge( NewEdge, theLine, Cone, BRep_Tool::Tolerance( Circ ) );
BB.Range( NewEdge, 0., 2.*M_PI );
BB.SameParameter( NewEdge, Standard_True );
BB.SameRange( NewEdge, Standard_True );
BB.Degenerated( NewEdge, Standard_True );
TopoDS_Vertex Apex = BRepLib_MakeVertex( apex );
BB.Add( NewEdge, Apex.Oriented(TopAbs_FORWARD) );
BB.Add( NewEdge, Apex.Oriented(TopAbs_REVERSED) );
TopoDS_Vertex cver = TopExp::FirstVertex( Circ );
//Reconstructing Seam
Standard_Real f, l, par, cpar;
Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( Seam, Cone, f, l );
gp_Lin2d aLine = (Handle(Geom2d_Line)::DownCast(theCurve))->Lin2d();
par = ElCLib::Parameter( aLine, gp_Pnt2d( Uapex, Vapex ) );
cpar = BRep_Tool::Parameter( cver, Seam, Cone );
if (Abs(f-cpar) < Abs(l-cpar))
BB.Range( Seam, par, l );
else
BB.Range( Seam, f, par );
Seam.Free( Standard_True );
TopoDS_Shape cver1;
TopoDS_Iterator iter( Seam );
for (; iter.More(); iter.Next())
{
cver1 = iter.Value();
if (cver1.IsSame(cver))
break;
}
BB.Remove( Seam, cver1 );
if (Abs(f-cpar) < Abs(l-cpar))
BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_FORWARD) ) );
else
BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_REVERSED) ) );
//Removing ExtraFace from the shell
fexp.Init( myOffsetShape, TopAbs_SHELL );
TopoDS_Shape theShell = fexp.Current();
theShell.Free( Standard_True );
TopoDS_Shape ExtraFace1;
for (iter.Initialize( theShell ); iter.More(); iter.Next())
{
ExtraFace1 = iter.Value();
if (ExtraFace1.IsSame(ExtraFace))
break;
}
BB.Remove( theShell, ExtraFace1 );
//Substitute Circ by NewEdge in Cone
TopoDS_Shape theWire;
TopoDS_Shape Circ1;
for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
{
theWire = fexp.Current();
Standard_Boolean found = Standard_False;
for (iter.Initialize( theWire ); iter.More(); iter.Next())
{
Circ1 = iter.Value();
if (Circ1.IsSame(Circ))
{
found = Standard_True;
break;
}
}
if (found)
break;
}
TopAbs_Orientation Or = Circ1.Orientation();
theWire.Free( Standard_True );
BB.Remove( theWire, Circ1 );
BB.Add( theWire, NewEdge.Oriented(Or) );
} //end of case 1
else // Circ is degenerated
{
if (myOffset > 0. && myJoin == GeomAbs_Arc) //case 2
{
TopoDS_Vertex cver = TopExp::FirstVertex( Circ );
TopoDS_Face OrCone = TopoDS::Face( myInitOffsetFace.Root( Cone ) );
Handle(Geom_Surface) aSurf = BRep_Tool::Surface( OrCone ), OffSurf = aSurf;
if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
gp_Pnt apex = theCone.Apex();
if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
{
Standard_Real Uapex, Vapex;
ElSLib::Parameters( theCone, apex, Uapex, Vapex );
apex = OffSurf->Value( Uapex, Vapex );
}
Standard_Real f, l;
Handle(Geom_Curve) ccur = BRep_Tool::Curve( Circ, f, l );
gp_Ax2 Axe2 = (Handle(Geom_Circle)::DownCast(ccur))->Circ().Position();
gp_Ax3 Axe3( Axe2 );
Axe3.SetLocation( apex );
gp_Sphere theSphere( Axe3, myOffset );
gp_Pnt OrPnt = BRep_Tool::Pnt(cver);
Standard_Real Uor, Vor;
ElSLib::Parameters( theSphere, OrPnt, Uor, Vor );
TopoDS_Face NewFace;
if (Vor > 0.)
NewFace = BRepLib_MakeFace( theSphere, 0., 2.*M_PI, Vor, M_PI/2. );
else
NewFace = BRepLib_MakeFace( theSphere, 0., 2.*M_PI, -M_PI/2., Vor );
//Updating the bound of NewFace
TopoDS_Edge Bound;
TopExp_Explorer eexp( NewFace, TopAbs_EDGE );
for (; eexp.More(); eexp.Next())
{
Bound = TopoDS::Edge( eexp.Current() );
Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Bound.TShape());
if (!TE->Degenerated() && !BRepTools::IsReallyClosed( Bound, NewFace ))
break;
}
Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( Circ, Cone, f, l );
BB.UpdateEdge( Bound, pcurve, Cone, BRep_Tool::Tolerance(Circ) );
TopoDS_Vertex bver = TopExp::FirstVertex( Bound );
BB.UpdateVertex( bver, BRep_Tool::Tolerance(cver) );
//Updating cver in Seam
TopoDS_Vertex cver1;
TopoDS_Iterator iter( Seam );
for (; iter.More(); iter.Next())
{
cver1 = TopoDS::Vertex( iter.Value() );
if (cver1.IsSame(cver))
break;
}
TopAbs_Orientation Or = cver1.Orientation();
Seam.Free( Standard_True );
BB.Remove( Seam, cver1 );
BB.Add( Seam, bver.Oriented(Or) );
//Substitute Circ by Bound in Cone
TopoDS_Shape theWire;
TopoDS_Shape Circ1;
for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
{
theWire = fexp.Current();
Standard_Boolean found = Standard_False;
for (iter.Initialize( theWire ); iter.More(); iter.Next())
{
Circ1 = iter.Value();
if (Circ1.IsSame(Circ))
{
found = Standard_True;
break;
}
}
if (found)
break;
}
Or = Circ1.Orientation();
theWire.Free( Standard_True );
BB.Remove( theWire, Circ1 );
BB.Add( theWire, Bound.Oriented(Or) );
//Adding NewFace to the shell
fexp.Init( myOffsetShape, TopAbs_SHELL );
TopoDS_Shape theShell = fexp.Current();
theShell.Free( Standard_True );
BB.Add( theShell, NewFace );
theShell.Closed( Standard_True );
} //end of case 2
else // if ((myOffset > 0. && myJoin == GeomAbs_Intersection) || myOffset < 0.) //case 3, 4
{
Handle(Geom_Surface) aSurf = BRep_Tool::Surface( Cone ), OffSurf = aSurf;
if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
gp_Pnt apex = theCone.Apex();
Standard_Real Uapex, Vapex;
ElSLib::Parameters( theCone, apex, Uapex, Vapex );
if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
apex = OffSurf->Value( Uapex, Vapex );
//Making new degenerated edge
Handle(Geom2d_Line) theLine = GCE2d_MakeLine( gp_Pnt2d( 0., Vapex ), gp_Pnt2d( 2.*M_PI, Vapex ) );
TopoDS_Edge NewEdge;
BB.MakeEdge( NewEdge );
NewEdge.Orientation(TopAbs_FORWARD);
BB.UpdateEdge( NewEdge, theLine, Cone, BRep_Tool::Tolerance( Circ ) );
BB.Range( NewEdge, 0., 2.*M_PI );
BB.SameParameter( NewEdge, Standard_True );
BB.SameRange( NewEdge, Standard_True );
BB.Degenerated( NewEdge, Standard_True );
TopoDS_Vertex Apex = BRepLib_MakeVertex( apex );
BB.Add( NewEdge, Apex.Oriented(TopAbs_FORWARD) );
BB.Add( NewEdge, Apex.Oriented(TopAbs_REVERSED) );
TopoDS_Vertex cver = TopExp::FirstVertex( Circ );
//Reconstructing Seam
Standard_Real f, l, par, cpar;
Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( Seam, Cone, f, l );
gp_Lin2d aLine = (Handle(Geom2d_Line)::DownCast(theCurve))->Lin2d();
par = ElCLib::Parameter( aLine, gp_Pnt2d( Uapex, Vapex ) );
cpar = BRep_Tool::Parameter( cver, Seam, Cone );
if (Abs(f-cpar) < Abs(l-cpar))
BB.Range( Seam, par, l );
else
BB.Range( Seam, f, par );
Seam.Free( Standard_True );
TopoDS_Shape cver1;
TopoDS_Iterator iter( Seam );
for (; iter.More(); iter.Next())
{
cver1 = iter.Value();
if (cver1.IsSame(cver))
break;
}
BB.Remove( Seam, cver1 );
if (Abs(f-cpar) < Abs(l-cpar))
BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_FORWARD) ) );
else
BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_REVERSED) ) );
//Substitute Circ by NewEdge in Cone
TopoDS_Shape theWire;
TopoDS_Shape Circ1;
for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
{
theWire = fexp.Current();
Standard_Boolean found = Standard_False;
for (iter.Initialize( theWire ); iter.More(); iter.Next())
{
Circ1 = iter.Value();
if (Circ1.IsSame(Circ))
{
found = Standard_True;
break;
}
}
if (found)
break;
}
TopAbs_Orientation Or = Circ1.Orientation();
theWire.Free( Standard_True );
BB.Remove( theWire, Circ1 );
BB.Add( theWire, NewEdge.Oriented(Or) );
fexp.Init( myOffsetShape, TopAbs_SHELL );
TopoDS_Shape theShell = fexp.Current();
theShell.Closed( Standard_True );
} //end of case 3, 4
}
} //else (! Circ.IsNull())
}
*/
Standard_Integer NbShell = 0; Standard_Integer NbShell = 0;
TopoDS_Compound NC; TopoDS_Compound NC;
TopoDS_Shape S1; TopoDS_Shape S1;
@ -2564,6 +2187,7 @@ void BRepOffset_MakeOffset::CorrectConicalFaces()
if (NbShell == 1) myOffsetShape = S1; if (NbShell == 1) myOffsetShape = S1;
else myOffsetShape = NC; else myOffsetShape = NC;
} }
}
//======================================================================= //=======================================================================

View File

@ -557,8 +557,12 @@ void BRepOffset_Offset::Init(const TopoDS_Face& Face,
BRepOffset::Surface( S, myOffset, myStatus); BRepOffset::Surface( S, myOffset, myStatus);
//processing offsets of faces with possible degenerated edges //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 VminDegen = Standard_False;
Standard_Boolean VmaxDegen = Standard_False; Standard_Boolean VmaxDegen = Standard_False;
Standard_Boolean UisoDegen = Standard_False;
Standard_Boolean VisoDegen = Standard_False;
gp_Pnt MinApex, MaxApex; gp_Pnt MinApex, MaxApex;
Standard_Boolean HasSingularity = Standard_False; Standard_Boolean HasSingularity = Standard_False;
Standard_Real uf1, uf2, vf1, vf2, fpar, lpar; Standard_Real uf1, uf2, vf1, vf2, fpar, lpar;
@ -578,21 +582,42 @@ void BRepOffset_Offset::Init(const TopoDS_Face& Face,
if (!DegEdges.IsEmpty()) if (!DegEdges.IsEmpty())
{ {
const Standard_Real TolApex = 1.e-5; 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) if (DegEdges.Length() == 2)
{ {
VminDegen = Standard_True; if (UisoDegen)
VmaxDegen = Standard_True; { UminDegen = Standard_True; UmaxDegen = Standard_True; }
else
{ VminDegen = Standard_True; VmaxDegen = Standard_True; }
} }
else //DegEdges.Length() == 1 else //DegEdges.Length() == 1
{ {
const TopoDS_Edge& theDegEdge = TopoDS::Edge(DegEdges(1)); const TopoDS_Edge& theDegEdge = TopoDS::Edge(DegEdges(1));
Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(theDegEdge, Face, fpar, lpar); Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(theDegEdge, Face, fpar, lpar);
gp_Pnt2d aPnt2d = aCurve->Value(fpar); if (UisoDegen)
if (Abs(aPnt2d.Y() - vf1) <= Precision::Confusion()) {
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; VminDegen = Standard_True;
else else
VmaxDegen = Standard_True; VmaxDegen = Standard_True;
} }
}
if (TheSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface)) if (TheSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
{ {
gp_Cone theCone = (*((Handle(Geom_ConicalSurface)*)&TheSurf))->Cone(); gp_Cone theCone = (*((Handle(Geom_ConicalSurface)*)&TheSurf))->Cone();
@ -614,18 +639,96 @@ void BRepOffset_Offset::Init(const TopoDS_Face& Face,
} }
else //TheSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface) 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) if (VminDegen)
{ {
Handle(Geom_Curve) viso = TheSurf->VIso( vf1 ); Handle(Geom_Curve) viso = TheSurf->VIso( vf1 );
if (BRepOffset_Tool::Gabarit( viso ) > TolApex) if (BRepOffset_Tool::Gabarit( viso ) > TolApex)
{ {
Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface(); Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface();
gp_Pnt Papex, Pfirst, Plast, Pmid; gp_Pnt Papex, Pfirst, Pquart, Pmid;
Papex = BasisSurf->Value( uf1, vf1 ); Papex = BasisSurf->Value( uf1, vf1 );
Pfirst = TheSurf->Value( uf1, vf1 ); Pfirst = TheSurf->Value( uf1, vf1 );
Plast = TheSurf->Value( uf2, vf1 ); Pquart = TheSurf->Value( 0.75*uf1+0.25*uf2, vf1 );
Pmid = TheSurf->Value( (uf1+uf2)/2., vf1 ); Pmid = TheSurf->Value( 0.5*(uf1+uf2), vf1 );
gp_Vec DirApex = gp_Vec(Pfirst,Pmid) ^ gp_Vec(Pfirst,Plast); gp_Vec DirApex = gp_Vec(Pfirst,Pquart) ^ gp_Vec(Pfirst,Pmid);
Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex ); Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf1, 0, 1 ); gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf1, 0, 1 );
Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix ); Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
@ -661,12 +764,12 @@ void BRepOffset_Offset::Init(const TopoDS_Face& Face,
if (BRepOffset_Tool::Gabarit( viso ) > TolApex) if (BRepOffset_Tool::Gabarit( viso ) > TolApex)
{ {
Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface(); Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface();
gp_Pnt Papex, Pfirst, Plast, Pmid; gp_Pnt Papex, Pfirst, Pquart, Pmid;
Papex = BasisSurf->Value( uf1, vf2 ); Papex = BasisSurf->Value( uf1, vf2 );
Pfirst = TheSurf->Value( uf1, vf2 ); Pfirst = TheSurf->Value( uf1, vf2 );
Plast = TheSurf->Value( uf2, vf2 ); Pquart = TheSurf->Value( 0.75*uf1+0.25*uf2, vf2 );
Pmid = TheSurf->Value( (uf1+uf2)/2., vf2 ); Pmid = TheSurf->Value( 0.5*(uf1+uf2), vf2 );
gp_Vec DirApex = gp_Vec(Pfirst,Pmid) ^ gp_Vec(Pfirst,Plast); gp_Vec DirApex = gp_Vec(Pfirst,Pquart) ^ gp_Vec(Pfirst,Pmid);
Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex ); Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf2, 0, 1 ); gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf2, 0, 1 );
Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix ); Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );

View File

@ -0,0 +1,27 @@
puts "================"
puts "OCC25406"
puts "================"
puts ""
##################################
# BRepOffset_MakeOffset algorithm fails on the face with two degenerated edges on u-iso null curves
##################################
restore [locate_data_file bug25406_offset_shape.brep] a
offsetshape result a 10
set length 1875.31
set nb_v_good 2
set nb_e_good 4
set nb_w_good 1
set nb_f_good 1
set nb_sh_good 1
set nb_sol_good 0
set nb_compsol_good 0
set nb_compound_good 0
set nb_shape_good 9
smallview
fit
set only_screen_axo 1

View File

@ -0,0 +1,27 @@
puts "================"
puts "OCC25406"
puts "================"
puts ""
##################################
# BRepOffset_MakeOffset algorithm fails on the face with two degenerated edges on u-iso null curves
##################################
restore [locate_data_file bug25406_offset_shape.brep] a
offsetshape result a -10
set length 1875.31
set nb_v_good 2
set nb_e_good 4
set nb_w_good 1
set nb_f_good 1
set nb_sh_good 1
set nb_sol_good 0
set nb_compsol_good 0
set nb_compound_good 0
set nb_shape_good 9
smallview
fit
set only_screen_axo 1