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.
This commit is contained in:
tetektoza
2025-10-26 14:45:28 +01:00
parent bdbac7d10b
commit df04761bae

View File

@@ -294,38 +294,43 @@ TopoDS_Wire ImpExpDxfRead::BuildWireFromPolyline(std::list<VertexInfo>& 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);
}
}