mirror of https://github.com/KLayout/klayout.git
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:
parent
563f1026e8
commit
35e42a8117
|
|
@ -814,10 +814,10 @@ De Boor algorithm for NURBS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static db::DPoint
|
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 ());
|
k = (int) (std::lower_bound (t.begin (), t.end (), x - 1e-6) - t.begin ());
|
||||||
if (k <= p) {
|
if (k < p) {
|
||||||
return control_points.front ().first;
|
return control_points.front ().first;
|
||||||
} else if (k > (int) control_points.size ()) {
|
} else if (k > (int) control_points.size ()) {
|
||||||
return control_points.back ().first;
|
return control_points.back ().first;
|
||||||
|
|
@ -878,14 +878,16 @@ spline_interpolate (std::list<db::DPoint> &curve_points,
|
||||||
std::list<db::DPoint>::iterator pe = pm;
|
std::list<db::DPoint>::iterator pe = pm;
|
||||||
++pe;
|
++pe;
|
||||||
|
|
||||||
db::DPoint s1 = b_spline_point (t_start + 0.5 * dt, control_points, degree, knots);
|
int k1 = 0, k2 = 0;
|
||||||
db::DPoint s2 = b_spline_point (t_start + 1.5 * dt, control_points, degree, knots);
|
|
||||||
|
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 p1 (s1, *current_curve_point);
|
||||||
db::DVector p2 (*pm, s1);
|
db::DVector p2 (*pm, s1);
|
||||||
double pl1 = p1.length(), pl2 = p2.length();
|
double pl1 = p1.length(), pl2 = p2.length();
|
||||||
|
|
||||||
if (curve_points.size () < control_points.size () - degree - 1) {
|
if (k1 != k2) {
|
||||||
|
|
||||||
curve_points.insert (pm, s1);
|
curve_points.insert (pm, s1);
|
||||||
spline_interpolate (curve_points, current_curve_point, t_start, dt * 0.5, control_points, degree, knots, sin_da, accu);
|
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);
|
double accu = std::max (m_circle_accuracy, m_dbu / m_unit);
|
||||||
|
|
||||||
std::list<db::DPoint> new_points;
|
std::list<db::DPoint> new_points;
|
||||||
new_points.push_back (control_points.front ().first);
|
|
||||||
|
|
||||||
double dt = 0.5 * (tn - t0);
|
double dt = 0.5 * (tn - t0);
|
||||||
|
|
||||||
for (double t = t0 + dt; t < tn + 1e-6; t += dt) {
|
for (double t = t0; t < tn + 1e-6; t += dt) {
|
||||||
db::DPoint s = b_spline_point (t, control_points, degree, knots);
|
int k = 0;
|
||||||
|
db::DPoint s = b_spline_point (t, control_points, degree, knots, k);
|
||||||
new_points.push_back (s);
|
new_points.push_back (s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ TEST(15)
|
||||||
db::DXFReaderOptions opt;
|
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.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;
|
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)
|
TEST(16)
|
||||||
|
|
@ -190,7 +190,7 @@ TEST(16)
|
||||||
db::DXFReaderOptions opt;
|
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.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;
|
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)
|
TEST(17)
|
||||||
|
|
@ -198,7 +198,7 @@ TEST(17)
|
||||||
db::DXFReaderOptions opt;
|
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.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;
|
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)
|
TEST(18)
|
||||||
|
|
@ -515,3 +515,12 @@ TEST(34)
|
||||||
|
|
||||||
run_test_public (_this, "issue_1173.dxf", "issue_1173_au.gds.gz", opt);
|
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);
|
||||||
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Loading…
Reference in New Issue