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:
parent
09c597c998
commit
903f7584b8
@ -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;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
@ -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 );
|
||||||
|
27
tests/bugs/modalg_5/bug25406_1
Normal file
27
tests/bugs/modalg_5/bug25406_1
Normal 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
|
27
tests/bugs/modalg_5/bug25406_2
Normal file
27
tests/bugs/modalg_5/bug25406_2
Normal 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
|
Loading…
x
Reference in New Issue
Block a user