diff --git a/src/plugins/streamers/dxf/db_plugin/dbDXFReader.cc b/src/plugins/streamers/dxf/db_plugin/dbDXFReader.cc index ec409cbf2..160fcf1cb 100644 --- a/src/plugins/streamers/dxf/db_plugin/dbDXFReader.cc +++ b/src/plugins/streamers/dxf/db_plugin/dbDXFReader.cc @@ -816,7 +816,9 @@ De Boor algorithm for NURBS static db::DPoint b_spline_point (double x, const std::vector > &control_points, int p, const std::vector &t, int &k) { - k = (int) (std::lower_bound (t.begin (), t.end (), x - 1e-6) - t.begin ()); + double eps = 1e-12 * (fabs (t.back ()) + fabs (t.front ())); + + k = (int) (std::lower_bound (t.begin (), t.end (), x - eps) - t.begin ()); --k; if (k < p) { k = p; @@ -882,6 +884,12 @@ spline_interpolate (std::list &curve_points, 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); +if (s1.to_string () == "-2.60657790172,-1.78843428245") { + tl::info << "@@@ BANG!"; +} +if (s2.to_string () == "-2.60657790172,-1.78843428245") { + tl::info << "@@@ BANG!"; +} db::DVector p1 (s1, *current_curve_point); db::DVector p2 (*pm, s1); @@ -1740,6 +1748,7 @@ DXFReader::read_entities (db::Layout &layout, db::Cell &cell, const db::DVector std::string layer; unsigned int xy_flag = 0; int degree = 1; + int flags = 0; while ((g = read_group_code ()) != 0) { if (g == 8) { @@ -1763,9 +1772,9 @@ DXFReader::read_entities (db::Layout &layout, db::Cell &cell, const db::DVector } else if (g == 70) { - int flags = read_int32 (); - if (flags != 8 && flags != 12) { - warn ("Invalid SPLINE flag (code 70): " + tl::to_string (flags) + ". Only types 8 (non-rational) and 12 (rational) are supported currently."); + flags = read_int32 (); + if ((flags & 2) != 0) { + warn ("Invalid SPLINE flag (code 70): " + tl::to_string (flags) + ". Periodic splines not supported currently."); } } else if (g == 71) { @@ -1814,6 +1823,13 @@ DXFReader::read_entities (db::Layout &layout, db::Cell &cell, const db::DVector } } + } else if ((flags & 1) && m_polyline_mode == 2) { + + // create a polygon for the spline + db::DSimplePolygon p; + p.assign_hull (new_points.begin (), new_points.end (), tt); + cell.shapes (ll.second).insert (safe_from_double (p)); + } else { // create a path with width 0 for the spline diff --git a/src/plugins/streamers/dxf/unit_tests/dbDXFReaderTests.cc b/src/plugins/streamers/dxf/unit_tests/dbDXFReaderTests.cc index d38d5ed20..87ba522e7 100644 --- a/src/plugins/streamers/dxf/unit_tests/dbDXFReaderTests.cc +++ b/src/plugins/streamers/dxf/unit_tests/dbDXFReaderTests.cc @@ -536,3 +536,20 @@ TEST(35c) db::DXFReaderOptions opt; run_test_public (_this, "issue_1422c.dxf", "issue_1422c_au.gds.gz", opt); } + +// issue #1592, polyline mode 2 +TEST(36a) +{ + db::DXFReaderOptions opt; + opt.dbu = 1e-5; + opt.polyline_mode = 2; + run_test_public (_this, "issue_1592.dxf.gz", "issue_1592a_au.oas.gz", opt, true); +} + +// issue #1592 +TEST(36b) +{ + db::DXFReaderOptions opt; + opt.dbu = 1e-5; + run_test_public (_this, "issue_1592.dxf.gz", "issue_1592b_au.oas.gz", opt, true); +} diff --git a/testdata/dxf/issue_1592.dxf.gz b/testdata/dxf/issue_1592.dxf.gz new file mode 100644 index 000000000..76ddf557d Binary files /dev/null and b/testdata/dxf/issue_1592.dxf.gz differ diff --git a/testdata/dxf/issue_1592a_au.oas.gz b/testdata/dxf/issue_1592a_au.oas.gz new file mode 100644 index 000000000..61bce16f7 Binary files /dev/null and b/testdata/dxf/issue_1592a_au.oas.gz differ diff --git a/testdata/dxf/issue_1592b_au.oas.gz b/testdata/dxf/issue_1592b_au.oas.gz new file mode 100644 index 000000000..a55226a25 Binary files /dev/null and b/testdata/dxf/issue_1592b_au.oas.gz differ