From a56d85bf15a5b1d695be69cd321760862e8aa588 Mon Sep 17 00:00:00 2001 From: Dmitrii Kulikov <164657232+AtheneNoctuaPt@users.noreply.github.com> Date: Thu, 15 May 2025 19:35:52 +0100 Subject: [PATCH] Modeling - BRepFilletAPI_MakeFillet Segfault with two curves and rim #532 Added null checks for TopoDS_Face in ChFi3d_Builder_2 and BRepAdaptor_Surface. Added tests to check for crash. --- .../TKFillet/ChFi3d/ChFi3d_Builder_2.cxx | 19 ++-- .../BRepAdaptor/BRepAdaptor_Surface.cxx | 5 + tests/bugs/modalg_8/bug_gh501 | 96 +++++++++++++++++++ 3 files changed, 111 insertions(+), 9 deletions(-) create mode 100644 tests/bugs/modalg_8/bug_gh501 diff --git a/src/ModelingAlgorithms/TKFillet/ChFi3d/ChFi3d_Builder_2.cxx b/src/ModelingAlgorithms/TKFillet/ChFi3d/ChFi3d_Builder_2.cxx index a4da2dd891..5e7ad10bab 100644 --- a/src/ModelingAlgorithms/TKFillet/ChFi3d/ChFi3d_Builder_2.cxx +++ b/src/ModelingAlgorithms/TKFillet/ChFi3d/ChFi3d_Builder_2.cxx @@ -1097,22 +1097,23 @@ static void ChFi3d_BuildPlane(TopOpeBRepDS_DataStructure& DStr, const Standard_Boolean isfirst, const Standard_Integer ons) { - Handle(Geom2d_Curve) Hc; - TopoDS_Face F = TopoDS::Face(DStr.Shape(SD->Index(ons))); - Standard_Real u, v; - gp_Pnt P; - // gp_Vec V1,V2; + const TopoDS_Face F = TopoDS::Face(DStr.Shape(SD->Index(ons))); + if (F.IsNull()) + { + return; + } if (SD->Vertex(isfirst, ons).IsOnArc()) { - Hc = BRep_Tool::CurveOnSurface(SD->Vertex(isfirst, ons).Arc(), F, u, v); + Standard_Real u, v; + const Handle(Geom2d_Curve) Hc = + BRep_Tool::CurveOnSurface(SD->Vertex(isfirst, ons).Arc(), F, u, v); Hc->Value(SD->Vertex(isfirst, ons).ParameterOnArc()).Coord(u, v); BRepLProp_SLProps theProp(*HS, u, v, 1, 1.e-12); if (theProp.IsNormalDefined()) { - P = theProp.Value(); - Handle(Geom_Plane) Pln = new Geom_Plane(P, theProp.Normal()); - TopoDS_Face NewF = BRepLib_MakeFace(Pln, Precision::Confusion()); + const Handle(Geom_Plane) Pln = new Geom_Plane(theProp.Value(), theProp.Normal()); + TopoDS_Face NewF = BRepLib_MakeFace(Pln, Precision::Confusion()); NewF.Orientation(F.Orientation()); pons.SetCoord(0., 0.); HS->Initialize(NewF); diff --git a/src/ModelingData/TKBRep/BRepAdaptor/BRepAdaptor_Surface.cxx b/src/ModelingData/TKBRep/BRepAdaptor/BRepAdaptor_Surface.cxx index 06a81f2cdf..653db6504b 100644 --- a/src/ModelingData/TKBRep/BRepAdaptor/BRepAdaptor_Surface.cxx +++ b/src/ModelingData/TKBRep/BRepAdaptor/BRepAdaptor_Surface.cxx @@ -70,6 +70,11 @@ Handle(Adaptor3d_Surface) BRepAdaptor_Surface::ShallowCopy() const void BRepAdaptor_Surface::Initialize(const TopoDS_Face& F, const Standard_Boolean Restriction) { + if (F.IsNull()) + { + return; + } + myFace = F; TopLoc_Location L; const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface(F, L); diff --git a/tests/bugs/modalg_8/bug_gh501 b/tests/bugs/modalg_8/bug_gh501 new file mode 100644 index 0000000000..4ebe36b7b2 --- /dev/null +++ b/tests/bugs/modalg_8/bug_gh501 @@ -0,0 +1,96 @@ +# This test case is to reproduce the crash during blend operation +# Given a geometry with two curves and a "rim" at the end, performing +# a fillet with a radius that is too large leads to a segfault. + +dset tolerance 0.0001 + +# back edge +dset xEdgeBackLeft -5 +vertex vEdgeBackRight 0 0 0 +vertex vEdgeBackLeft xEdgeBackLeft 0 0 +edge edgeBack vEdgeBackLeft vEdgeBackRight + +# edge circle at the back +dset radiusCircleBack 5.56 +dset angleCircleBackStart -0.755726 +dset xCircleBack xEdgeBackLeft-radiusCircleBack + +circle circleBack xCircleBack 0 0 radiusCircleBack +mkedge edgeCircleBack circleBack angleCircleBackStart 0 +settolerance edgeCircleBack tolerance + +# edge circle at the front +dset radiusCircleFrontBottom 8.95 +dset angleCircleFrontBottomStart 2.385867 +dset angleCircleFrontBottomEnd -2.163565 +dset yCircleFrontBottom -9.95121 + +circle circleFrontBottom 0 yCircleFrontBottom 0 radiusCircleFrontBottom +mkedge edgeCircleFrontBottom circleFrontBottom angleCircleFrontBottomStart angleCircleFrontBottomEnd +settolerance edgeCircleFrontBottom tolerance + +# edge at the front and bottom +dset yEdgeFrontBottom -17.374312 +dset xEdgeFrontBottomLeft xEdgeBackLeft +vertex vEdgeFrontBottomLeft xEdgeFrontBottomLeft yEdgeFrontBottom 0 +vertex vEdgeFrontBottomRight 0 yEdgeFrontBottom 0 +edge edgeFrontBottom vEdgeFrontBottomLeft vEdgeFrontBottomRight + +# edge at the right bottom +edge edgeRightBottom vEdgeFrontBottomRight vEdgeBackRight + +# the bottom wire +wire wireBottom edgeBack edgeCircleBack edgeCircleFrontBottom edgeFrontBottom edgeRightBottom + +# the bottom face +mkplane planeBottom wireBottom + +# the bottom solid +dset heightBottom 10.0 +prism solidBottom planeBottom 0 0 heightBottom + +# the top circle +dset yCircleTop yCircleFrontBottom +dset radiusCircleTop 8.57 +dset angleCircleTopStart pi/2 +dset angleCircleTop 2.618290 +dset angleYAxis pi-angleCircleTop +dset angleCircleTopEnd angleCircleTopStart+angleCircleTop +circle circleTop 0 yCircleTop heightBottom radiusCircleTop +mkedge edgeCircleTop circleTop angleCircleTopStart angleCircleTopEnd +settolerance edgeCircleTop tolerance + +# edge at the front at the top +dset yEdgeFrontTop yEdgeFrontBottom +dset xEdgeFrontTopLeft 0-radiusCircleTop*sin(angleYAxis) +vertex vEdgeFrontTopLeft xEdgeFrontTopLeft yEdgeFrontTop heightBottom +vertex vEdgeFrontTopRight 0 yEdgeFrontTop heightBottom +edge edgeFrontTop vEdgeFrontTopLeft vEdgeFrontTopRight +settolerance edgeFrontTop tolerance + +# edge at the right at the top +dset yEdgeRightTopBack yCircleTop+radiusCircleTop +dset yEdgeRightTopFront yEdgeFrontBottom +vertex vEdgeRightTopBack 0 yEdgeRightTopBack heightBottom +vertex vEdgeRightTopFront 0 yEdgeRightTopFront heightBottom +edge edgeRightTop vEdgeRightTopBack vEdgeRightTopFront + +# the top wire +wire wireTop edgeCircleTop edgeFrontTop edgeRightTop + +# the top face +mkplane planeTop wireTop + +# the top solid +dset heightTop 10.0 +prism solidTop planeTop 0 0 heightTop + +bop solidBottom solidTop +bopfuse fuse +explode fuse E + +# Algorithm is expected to fail with a Tcl exception. +puts "TODO ALL: Tcl Exception: tolerance ang" +puts "TODO ALL: TEST INCOMPLETE" + +blend b fuse 1 fuse_14