From 0cfa5ba5fe9cb94d41d4e71bdd27d58ba719b234 Mon Sep 17 00:00:00 2001 From: tetektoza Date: Sun, 26 Oct 2025 14:45:28 +0100 Subject: [PATCH] Fix: Closed polylines import duplicate vertices Similar case to the previous commit related to closed polylines having coincident vertices, but this time for import. Basically if importing DXF files containing closed polylines, FC would throw an exception. This was because `BuildWireFromPolyline()` function in the DXF importer attempted to create a closing edge for closed polylines by connecting the last vertex back to first vertex. So, this patch adds a skip for the closing edge if the vertices are coincident. --- src/Mod/Import/App/dxf/ImpExpDxf.cpp | 61 +++++++++++++++------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/src/Mod/Import/App/dxf/ImpExpDxf.cpp b/src/Mod/Import/App/dxf/ImpExpDxf.cpp index a6f0c69b2c..8fbf5c9c06 100644 --- a/src/Mod/Import/App/dxf/ImpExpDxf.cpp +++ b/src/Mod/Import/App/dxf/ImpExpDxf.cpp @@ -294,38 +294,43 @@ TopoDS_Wire ImpExpDxfRead::BuildWireFromPolyline(std::list& vertices if (is_closed && vertices.size() > 1) { const VertexInfo& start_vertex = vertices.back(); const VertexInfo& end_vertex = vertices.front(); - TopoDS_Edge edge; - if (start_vertex.bulge == 0.0) { - edge = BRepBuilderAPI_MakeEdge(makePoint(start_vertex.location), - makePoint(end_vertex.location)) - .Edge(); - } - else { - double cot = ((1.0 / start_vertex.bulge) - start_vertex.bulge) / 2.0; - double center_x = ((start_vertex.location.x + end_vertex.location.x) - - (end_vertex.location.y - start_vertex.location.y) * cot) - / 2.0; - double center_y = ((start_vertex.location.y + end_vertex.location.y) - + (end_vertex.location.x - start_vertex.location.x) * cot) - / 2.0; - double center_z = (start_vertex.location.z + end_vertex.location.z) / 2.0; - Base::Vector3d center(center_x, center_y, center_z); + // check if the vertices are coincident (distance < tolerance) + // if they are, the polyline is already closed and we don't need a closing edge + gp_Pnt p0 = makePoint(start_vertex.location); + gp_Pnt p1 = makePoint(end_vertex.location); + double distance = p0.Distance(p1); - gp_Pnt p0 = makePoint(start_vertex.location); - gp_Pnt p1 = makePoint(end_vertex.location); - gp_Dir up(0, 0, 1); - if (start_vertex.bulge < 0) { - up.Reverse(); + if (distance > Precision::Confusion()) { + TopoDS_Edge edge; + + if (start_vertex.bulge == 0.0) { + edge = BRepBuilderAPI_MakeEdge(p0, p1).Edge(); } - gp_Pnt pc = makePoint(center); - gp_Circ circle(gp_Ax2(pc, up), p0.Distance(pc)); - if (circle.Radius() > 1e-9) { - edge = BRepBuilderAPI_MakeEdge(circle, p0, p1).Edge(); + else { + double cot = ((1.0 / start_vertex.bulge) - start_vertex.bulge) / 2.0; + double center_x = ((start_vertex.location.x + end_vertex.location.x) + - (end_vertex.location.y - start_vertex.location.y) * cot) + / 2.0; + double center_y = ((start_vertex.location.y + end_vertex.location.y) + + (end_vertex.location.x - start_vertex.location.x) * cot) + / 2.0; + double center_z = (start_vertex.location.z + end_vertex.location.z) / 2.0; + Base::Vector3d center(center_x, center_y, center_z); + + gp_Dir up(0, 0, 1); + if (start_vertex.bulge < 0) { + up.Reverse(); + } + gp_Pnt pc = makePoint(center); + gp_Circ circle(gp_Ax2(pc, up), p0.Distance(pc)); + if (circle.Radius() > 1e-9) { + edge = BRepBuilderAPI_MakeEdge(circle, p0, p1).Edge(); + } + } + if (!edge.IsNull()) { + wireBuilder.Add(edge); } - } - if (!edge.IsNull()) { - wireBuilder.Add(edge); } }