Fixed issue-1422 (DXF file parsing error)

Problem were two spline interpolation issues:
1. wrong stop criterion for recursion
2. wrong implementation of single-point interpolation
This commit is contained in:
Matthias Koefferlein 2023-07-15 16:05:40 +02:00
parent 563f1026e8
commit 35e42a8117
8 changed files with 25225 additions and 12 deletions

View File

@ -814,10 +814,10 @@ De Boor algorithm for NURBS
*/
static db::DPoint
b_spline_point (double x, const std::vector<std::pair<db::DPoint, double> > &control_points, int p, const std::vector<double> &t)
b_spline_point (double x, const std::vector<std::pair<db::DPoint, double> > &control_points, int p, const std::vector<double> &t, int &k)
{
int k = (int) (std::lower_bound (t.begin (), t.end (), x + 1e-6) - t.begin ());
if (k <= p) {
k = (int) (std::lower_bound (t.begin (), t.end (), x - 1e-6) - t.begin ());
if (k < p) {
return control_points.front ().first;
} else if (k > (int) control_points.size ()) {
return control_points.back ().first;
@ -878,14 +878,16 @@ spline_interpolate (std::list<db::DPoint> &curve_points,
std::list<db::DPoint>::iterator pe = pm;
++pe;
db::DPoint s1 = b_spline_point (t_start + 0.5 * dt, control_points, degree, knots);
db::DPoint s2 = b_spline_point (t_start + 1.5 * dt, control_points, degree, knots);
int k1 = 0, k2 = 0;
db::DPoint s1 = b_spline_point (t_start + 0.5 * dt, control_points, degree, knots, k1);
db::DPoint s2 = b_spline_point (t_start + 1.5 * dt, control_points, degree, knots, k2);
db::DVector p1 (s1, *current_curve_point);
db::DVector p2 (*pm, s1);
double pl1 = p1.length(), pl2 = p2.length();
if (curve_points.size () < control_points.size () - degree - 1) {
if (k1 != k2) {
curve_points.insert (pm, s1);
spline_interpolate (curve_points, current_curve_point, t_start, dt * 0.5, control_points, degree, knots, sin_da, accu);
@ -958,12 +960,12 @@ DXFReader::spline_interpolation (std::vector<std::pair<db::DPoint, double> > &co
double accu = std::max (m_circle_accuracy, m_dbu / m_unit);
std::list<db::DPoint> new_points;
new_points.push_back (control_points.front ().first);
double dt = 0.5 * (tn - t0);
for (double t = t0 + dt; t < tn + 1e-6; t += dt) {
db::DPoint s = b_spline_point (t, control_points, degree, knots);
for (double t = t0; t < tn + 1e-6; t += dt) {
int k = 0;
db::DPoint s = b_spline_point (t, control_points, degree, knots, k);
new_points.push_back (s);
}

View File

@ -182,7 +182,7 @@ TEST(15)
db::DXFReaderOptions opt;
opt.layer_map = string2lm ("TEXT:4,IGBT:5,Wire:7,Ceramic:11,LAYER_1:14,Diode:18,'DBC TOP Plate':19,'Terminal Position':20");
opt.create_other_layers = true;
run_test (_this, "t15.dxf.gz", "t15_au2.gds.gz", opt);
run_test (_this, "t15.dxf.gz", "t15_au2_2.gds.gz", opt);
}
TEST(16)
@ -190,7 +190,7 @@ TEST(16)
db::DXFReaderOptions opt;
opt.layer_map = string2lm ("TEXT:4,IGBT:5,Wire:7,Ceramic:11,LAYER_1:14,Diode:18,'DBC TOP Plate':19,'Terminal Position':20");
opt.create_other_layers = true;
run_test (_this, "t16.dxf.gz", "t16_au2.gds.gz", opt);
run_test (_this, "t16.dxf.gz", "t16_au2_2.gds.gz", opt);
}
TEST(17)
@ -198,7 +198,7 @@ TEST(17)
db::DXFReaderOptions opt;
opt.layer_map = string2lm ("TEXT:4,IGBT:5,Wire:7,Ceramic:11,LAYER_1:14,Diode:18,'DBC TOP Plate':19,'Terminal Position':20");
opt.create_other_layers = true;
run_test (_this, "t17.dxf.gz", "t17_au2.gds.gz", opt);
run_test (_this, "t17.dxf.gz", "t17_au2_2.gds.gz", opt);
}
TEST(18)
@ -515,3 +515,12 @@ TEST(34)
run_test_public (_this, "issue_1173.dxf", "issue_1173_au.gds.gz", opt);
}
// issue #1422
TEST(35)
{
db::DXFReaderOptions opt;
run_test_public (_this, "issue_1422a.dxf", "issue_1422a_au.gds.gz", opt);
run_test_public (_this, "issue_1422b.dxf", "issue_1422b_au.gds.gz", opt);
run_test_public (_this, "issue_1422c.dxf", "issue_1422c_au.gds.gz", opt);
}

5434
testdata/dxf/issue_1422a.dxf vendored Normal file

File diff suppressed because it is too large Load Diff

BIN
testdata/dxf/issue_1422a_au.gds.gz vendored Normal file

Binary file not shown.

7516
testdata/dxf/issue_1422b.dxf vendored Normal file

File diff suppressed because it is too large Load Diff

BIN
testdata/dxf/issue_1422b_au.gds.gz vendored Normal file

Binary file not shown.

12252
testdata/dxf/issue_1422c.dxf vendored Normal file

File diff suppressed because it is too large Load Diff

BIN
testdata/dxf/issue_1422c_au.gds.gz vendored Normal file

Binary file not shown.