From 660d4edbefec92fb5a0a801d507384c37e28573f Mon Sep 17 00:00:00 2001 From: Kris Austin Date: Thu, 8 Oct 2026 11:34:26 -0500 Subject: [PATCH 1/2] Mesh - Fix cone faces left untriangulated when the seam pcurve is tilted SeamEdgeAmplifier::splitEdge matched the two seam pcurves by evaluating one of them at FirstParameter(). For an infinite Geom2d_Line that is -2e100, so a direction of (2e-16, -1) from rounding error gave an X far outside the U range and the pcurves were always swapped. Evaluate at the edge's first parameter instead. --- .../BRepMesh/BRepMesh_ModelPreProcessor.cxx | 8 ++- .../GTests/BRepMesh_IncrementalMesh_Test.cxx | 72 +++++++++++++++++++ 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/src/ModelingAlgorithms/TKMesh/BRepMesh/BRepMesh_ModelPreProcessor.cxx b/src/ModelingAlgorithms/TKMesh/BRepMesh/BRepMesh_ModelPreProcessor.cxx index 6f637819bd7..9b1c08ece59 100644 --- a/src/ModelingAlgorithms/TKMesh/BRepMesh/BRepMesh_ModelPreProcessor.cxx +++ b/src/ModelingAlgorithms/TKMesh/BRepMesh/BRepMesh_ModelPreProcessor.cxx @@ -210,10 +210,10 @@ class SeamEdgeAmplifier // Define two pcurves of the seam-edge. occ::handle aPC1, aPC2; - double af, al; + double af, al, af1, al1; aE.Orientation(TopAbs_FORWARD); - aPC1 = BRep_Tool::CurveOnSurface(aE, aF, af, al); + aPC1 = BRep_Tool::CurveOnSurface(aE, aF, af1, al1); aE.Orientation(TopAbs_REVERSED); aPC2 = BRep_Tool::CurveOnSurface(aE, aF, af, al); @@ -224,7 +224,9 @@ class SeamEdgeAmplifier } // Select the correct pcurve of the seam-edge. - const gp_Pnt2d& aFPntOfPC1 = aPC1->Value(aPC1->FirstParameter()); + // Use the edge's first parameter. A Geom2d_Line's FirstParameter() is -Precision::Infinite(), + // where a direction of (2e-16, -1) from rounding error gives an X far outside the U range. + const gp_Pnt2d aFPntOfPC1 = aPC1->Value(af1); if (std::abs(aLPntOfIPC1.X() - aFPntOfPC1.X()) > Precision::Confusion()) { diff --git a/src/ModelingAlgorithms/TKMesh/GTests/BRepMesh_IncrementalMesh_Test.cxx b/src/ModelingAlgorithms/TKMesh/GTests/BRepMesh_IncrementalMesh_Test.cxx index ee3ea7405ce..9aff24cfca6 100644 --- a/src/ModelingAlgorithms/TKMesh/GTests/BRepMesh_IncrementalMesh_Test.cxx +++ b/src/ModelingAlgorithms/TKMesh/GTests/BRepMesh_IncrementalMesh_Test.cxx @@ -32,7 +32,10 @@ #include #include #include +#include #include +#include +#include #include #include #include @@ -585,3 +588,72 @@ TEST(BRepMesh_IncrementalMeshTest, LocalizedSplinePeaksRespectDeflection) EXPECT_LE(aMaxDistance, aParameters.Deflection); } } + +// Regression test for issue #572: a conical face must be meshed when its seam pcurves are +// infinite lines whose direction is tilted by rounding error. +TEST(BRepMesh_IncrementalMeshTest, ConeWithTiltedSeamPCurves_IsTriangulated) +{ + const double aVMin = -25.0 * std::sqrt(2.0); + const occ::handle aCone = + new Geom_ConicalSurface(gp::XOY(), M_PI / 4.0, 36.4); + const gp_Pnt aTopPnt = aCone->Value(0.0, 0.0); + const gp_Pnt aBottomPnt = aCone->Value(0.0, aVMin); + + int aReferenceTriangles = 0; + for (const double aTilt : {0.0, 2.0e-16, -2.0e-16}) + { + SCOPED_TRACE(aTilt); + const TopoDS_Vertex aTopVertex = BRepBuilderAPI_MakeVertex(aTopPnt); + const TopoDS_Vertex aBottomVertex = BRepBuilderAPI_MakeVertex(aBottomPnt); + const TopoDS_Edge aTopEdge = + BRepBuilderAPI_MakeEdge(aCone->VIso(0.0), aTopVertex, aTopVertex, 0.0, 2.0 * M_PI); + const TopoDS_Edge aBottomEdge = + BRepBuilderAPI_MakeEdge(aCone->VIso(aVMin), aBottomVertex, aBottomVertex, 0.0, 2.0 * M_PI); + const TopoDS_Edge aSeamEdge = + BRepBuilderAPI_MakeEdge(new Geom_Line(aTopPnt, gp_Dir(gp_Vec(aTopPnt, aBottomPnt))), + aTopVertex, + aBottomVertex, + 0.0, + -aVMin); + + BRep_Builder aBuilder; + TopoDS_Face aFace; + aBuilder.MakeFace(aFace, aCone, Precision::Confusion()); + aBuilder.UpdateEdge(aTopEdge, + new Geom2d_Line(gp_Pnt2d(0.0, 0.0), gp_Dir2d(1.0, 0.0)), + aFace, + Precision::Confusion()); + aBuilder.UpdateEdge(aBottomEdge, + new Geom2d_Line(gp_Pnt2d(0.0, aVMin), gp_Dir2d(1.0, 0.0)), + aFace, + Precision::Confusion()); + aBuilder.UpdateEdge(aSeamEdge, + new Geom2d_Line(gp_Pnt2d(0.0, 0.0), gp_Dir2d(aTilt, -1.0)), + new Geom2d_Line(gp_Pnt2d(2.0 * M_PI, 0.0), gp_Dir2d(aTilt, -1.0)), + aFace, + Precision::Confusion()); + + TopoDS_Wire aWire; + aBuilder.MakeWire(aWire); + aBuilder.Add(aWire, aTopEdge.Reversed()); + aBuilder.Add(aWire, aSeamEdge); + aBuilder.Add(aWire, aBottomEdge); + aBuilder.Add(aWire, aSeamEdge.Reversed()); + aBuilder.Add(aFace, aWire); + + BRepMesh_IncrementalMesh aMesher(aFace, 0.01); + ASSERT_TRUE(aMesher.IsDone()); + EXPECT_EQ(aMesher.GetStatusFlags(), IMeshData_NoError); + + TopLoc_Location aLocation; + const occ::handle aTriangulation = + BRep_Tool::Triangulation(aFace, aLocation); + ASSERT_FALSE(aTriangulation.IsNull()); + if (aTilt == 0.0) + { + aReferenceTriangles = aTriangulation->NbTriangles(); + EXPECT_GT(aReferenceTriangles, 0); + } + EXPECT_EQ(aTriangulation->NbTriangles(), aReferenceTriangles); + } +} From d13223a83e155e16424d970815a3acaade27ec5e Mon Sep 17 00:00:00 2001 From: Kris Austin Date: Thu, 8 Oct 2026 13:29:06 -0500 Subject: [PATCH 2/2] Retrigger CI