Fix: Closed polylines export duplicate vertices

AS the title says - when exporting closed curves (ellipses for example)
as polylines with the "Treat ellipses and splines as polylines" option,
the generated DXF file contained duplicate vertices. For example, an
ellipse polyline would have vertex1 and vertex40 which are identical in
terms of coordinates. This has caused exception upon importing.

Cause of that was that discretizer was blindly iterating through all
discretized points without checking if the first and last points are
coincident.

So, this patch adds a check for that to detect and skip the last
coincident point if it is in fact coincident during Export.
This commit is contained in:
tetektoza
2025-10-26 14:38:08 +01:00
parent e221cfd47a
commit 01777cb320
2 changed files with 36 additions and 27 deletions

View File

@@ -58,6 +58,7 @@
#include <gp_Elips.hxx>
#include <gp_Pnt.hxx>
#include <gp_Trsf.hxx>
#include <Precision.hxx>
#include <gp_Vec.hxx>
#include <fstream>
@@ -2028,9 +2029,10 @@ void ImpExpDxfWrite::exportLine(BRepAdaptor_Curve& c)
writeLine(start, end);
}
void ImpExpDxfWrite::exportLWPoly(BRepAdaptor_Curve& c)
// Helper function to discretize a curve into polyline vertices
// Returns true if discretization was successful and pd was populated
bool ImpExpDxfWrite::discretizeCurveToPolyline(BRepAdaptor_Curve& c, LWPolyDataOut& pd) const
{
LWPolyDataOut pd;
pd.Flag = c.IsClosed();
pd.Elev = 0.0;
pd.Thick = 0.0;
@@ -2041,14 +2043,35 @@ void ImpExpDxfWrite::exportLWPoly(BRepAdaptor_Curve& c)
GCPnts_UniformAbscissa discretizer;
discretizer.Initialize(c, optionMaxLength);
std::vector<point3D> points;
if (discretizer.IsDone() && discretizer.NbPoints() > 0) {
int nbPoints = discretizer.NbPoints();
for (int i = 1; i <= nbPoints; i++) {
gp_Pnt p = c.Value(discretizer.Parameter(i));
pd.Verts.push_back(gPntTopoint3D(p));
if (!discretizer.IsDone() || discretizer.NbPoints() <= 0) {
return false;
}
int nbPoints = discretizer.NbPoints();
// for closed curves, don't include the last point if it duplicates the first
int endIndex = nbPoints;
if (pd.Flag && nbPoints > 1) {
gp_Pnt pFirst = c.Value(discretizer.Parameter(1));
gp_Pnt pLast = c.Value(discretizer.Parameter(nbPoints));
if (pFirst.Distance(pLast) < Precision::Confusion()) {
endIndex = nbPoints - 1;
}
pd.nVert = discretizer.NbPoints();
}
for (int i = 1; i <= endIndex; i++) {
gp_Pnt p = c.Value(discretizer.Parameter(i));
pd.Verts.push_back(gPntTopoint3D(p));
}
pd.nVert = static_cast<int>(pd.Verts.size());
return true;
}
void ImpExpDxfWrite::exportLWPoly(BRepAdaptor_Curve& c)
{
LWPolyDataOut pd;
if (discretizeCurveToPolyline(c, pd)) {
writeLWPolyLine(pd);
}
}
@@ -2056,24 +2079,7 @@ void ImpExpDxfWrite::exportLWPoly(BRepAdaptor_Curve& c)
void ImpExpDxfWrite::exportPolyline(BRepAdaptor_Curve& c)
{
LWPolyDataOut pd;
pd.Flag = c.IsClosed();
pd.Elev = 0.0;
pd.Thick = 0.0;
pd.Extr.x = 0.0;
pd.Extr.y = 0.0;
pd.Extr.z = 1.0;
pd.nVert = 0;
GCPnts_UniformAbscissa discretizer;
discretizer.Initialize(c, optionMaxLength);
std::vector<point3D> points;
if (discretizer.IsDone() && discretizer.NbPoints() > 0) {
int nbPoints = discretizer.NbPoints();
for (int i = 1; i <= nbPoints; i++) {
gp_Pnt p = c.Value(discretizer.Parameter(i));
pd.Verts.push_back(gPntTopoint3D(p));
}
pd.nVert = discretizer.NbPoints();
if (discretizeCurveToPolyline(c, pd)) {
writePolyline(pd);
}
}

View File

@@ -542,6 +542,9 @@ protected:
void exportLWPoly(BRepAdaptor_Curve& c); // LWPolyline not supported in R12?
void exportPolyline(BRepAdaptor_Curve& c);
// helper function to discretize a curve into polyline vertices
bool discretizeCurveToPolyline(BRepAdaptor_Curve& c, LWPolyDataOut& pd) const;
// std::string m_optionSource;
double optionMaxLength;
bool optionPolyLine;