diff --git a/src/db/db/dbPolygonGenerators.cc b/src/db/db/dbPolygonGenerators.cc index ddaf33268c..f339611ed1 100644 --- a/src/db/db/dbPolygonGenerators.cc +++ b/src/db/db/dbPolygonGenerators.cc @@ -410,6 +410,8 @@ PolygonGenerator::begin_scanline (db::Coord y) m_open_pos = m_open.begin (); m_y = y; + m_prev_stitch_index = std::numeric_limits::max (); + #ifdef DEBUG_POLYGON_GENERATOR printf ("m_open="); for (open_map_type::const_iterator o = m_open.begin (); o != m_open.end (); ++o) { @@ -820,27 +822,68 @@ PolygonGenerator::join_contours (db::Coord x) tl_assert (c1.size () >= 2); PGPolyContour::iterator ins = cprev.end (); - db::Coord xprev = 0; - db::Edge eprev; -#if 1 + PGPolyContour::iterator ii = ins; + --ii; + PGPolyContour::iterator iii = ii; + --iii; + // shallow analysis: insert the cutline at the end of the sequence - this may // cut lines collinear with contour edges - eprev = db::Edge (*(ins - 2), *(ins - 1)); - xprev = db::coord_traits::rounded (edge_xaty (db::Edge (*(ins - 2), *(ins - 1)), m_y)); -#else - // deep analysis: determine insertion point: pick the one where the cutline is shortest + db::Edge eprev = db::Edge (*iii, *ii); + db::Coord xprev = db::coord_traits::rounded (edge_xaty (eprev, m_y)); + +#if 1 // experimental + if (m_prev_stitch_index == iprev) { + + auto i = m_prev_stitch_ins; + ii = i; + iii = --ii; + --iii; + + if (ii->y () >= m_y) { + + db::Edge ecut (*iii, *ii); + db::Coord xcut = db::coord_traits::rounded (edge_xaty (ecut, m_y)); + + if (iii->y () < m_y && xcut < c1.back ().x () && xcut > xprev) { + xprev = xcut; + eprev = ecut; + ins = i; + } + + } + + } else { + + // deep analysis: determine insertion point: pick the one where the cutline is shortest + // CAUTION: this may introduce a O(2) complexity in the number of holes along the x axis + + while (true) { + + auto i = ii; + + ii = iii; + if (ii == cprev.begin ()) { + break; + } - for (PGPolyContour::iterator i = ins; i > cprev.begin () + 1; --i) { + --iii; - db::Edge ecut (i[-2], i[-1]); - db::Coord xcut = db::coord_traits::rounded (edge_xaty (db::Edge (i[-2], i[-1]), m_y)); + if (ii->y () >= m_y) { + + db::Edge ecut (*iii, *ii); + db::Coord xcut = db::coord_traits::rounded (edge_xaty (ecut, m_y)); + + if (iii->y () < m_y && xcut < c1.back ().x () && xcut > xprev) { + xprev = xcut; + eprev = ecut; + ins = i; + } + + } - if (ins == i || (i[-1].y () >= m_y && i[-2].y () < m_y && xcut < c1.back ().x () && xcut > xprev)) { - xprev = xcut; - eprev = ecut; - ins = i; } } @@ -864,6 +907,11 @@ PolygonGenerator::join_contours (db::Coord x) } ins = cprev.insert (ins, pprev); + + // remember the insertion point - it may be a candidate to attach the next hole + m_prev_stitch_ins = ins; + m_prev_stitch_index = iprev; + ++ins; if (eprev.p2 () != pprev) { cprev.insert (ins, eprev.p2 ()); diff --git a/src/db/db/dbPolygonGenerators.h b/src/db/db/dbPolygonGenerators.h index cc34c8fce6..b576812f54 100644 --- a/src/db/db/dbPolygonGenerators.h +++ b/src/db/db/dbPolygonGenerators.h @@ -183,6 +183,8 @@ class DB_PUBLIC PolygonGenerator db::SimplePolygon m_spoly; static bool ms_compress; bool m_compress; + size_t m_prev_stitch_index; + std::list::iterator m_prev_stitch_ins; void join_contours (db::Coord x); void produce_poly (const PGPolyContour &c); diff --git a/src/plugins/streamers/gds2/unit_tests/dbGDS2WriterTests.cc b/src/plugins/streamers/gds2/unit_tests/dbGDS2WriterTests.cc index 4e62f3aa03..091a134728 100644 --- a/src/plugins/streamers/gds2/unit_tests/dbGDS2WriterTests.cc +++ b/src/plugins/streamers/gds2/unit_tests/dbGDS2WriterTests.cc @@ -1192,7 +1192,7 @@ TEST(121) { db::GDS2WriterOptions opt; opt.max_vertex_count = 4; - run_test (_this, "t121.oas.gz", "t121_au.gds.gz", true, opt); + run_test (_this, "t121.oas.gz", "t121_au_2.gds.gz", true, opt); } // Meta info diff --git a/src/plugins/streamers/pcb/unit_tests/dbGerberImport.cc b/src/plugins/streamers/pcb/unit_tests/dbGerberImport.cc index ea4bb68ac0..3fb4c1ddbf 100644 --- a/src/plugins/streamers/pcb/unit_tests/dbGerberImport.cc +++ b/src/plugins/streamers/pcb/unit_tests/dbGerberImport.cc @@ -33,7 +33,7 @@ #include -static void run_test (tl::TestBase *_this, const char *dir) +static void run_test (tl::TestBase *_this, const char *dir, const char *au_file = "au.oas.gz") { if (! tl::XMLParser::is_available ()) { throw tl::CancelException (); @@ -53,7 +53,7 @@ static void run_test (tl::TestBase *_this, const char *dir) reader.read (layout, options); } - db::compare_layouts (_this, layout, tl::testdata_private () + "/pcb/" + dir + "/au.oas.gz", db::WriteOAS, 1); + db::compare_layouts (_this, layout, tl::testdata_private () + "/pcb/" + dir + "/" + au_file, db::WriteOAS, 1); } TEST(0_Metadata) @@ -167,7 +167,7 @@ TEST(1) TEST(2) { - run_test (_this, "allegro"); + run_test (_this, "allegro", "au_2.oas.gz"); } TEST(3) @@ -199,13 +199,13 @@ TEST(7) TEST(8) { test_is_long_runner (); - run_test (_this, "microchip-2"); + run_test (_this, "microchip-2", "au_2.oas.gz"); } TEST(9) { test_is_long_runner (); - run_test (_this, "microchip-3"); + run_test (_this, "microchip-3", "au_2.oas.gz"); } TEST(10) @@ -236,7 +236,7 @@ TEST(14) TEST(15) { - run_test (_this, "gerbv_examples/polarity"); + run_test (_this, "gerbv_examples/polarity", "au_2.oas.gz"); } TEST(16) @@ -294,7 +294,7 @@ TEST(25) TEST(26) { test_is_long_runner (); - run_test (_this, "pos-neg"); + run_test (_this, "pos-neg", "au_2.oas.gz"); } TEST(27) @@ -334,12 +334,12 @@ TEST(X2_2e) TEST(X2_2f) { - run_test (_this, "x2-2f"); + run_test (_this, "x2-2f", "au_2.oas.gz"); } TEST(X2_2g) { - run_test (_this, "x2-2g"); + run_test (_this, "x2-2g", "au_2.oas.gz"); } TEST(X2_2h) @@ -364,7 +364,7 @@ TEST(X2_2k) TEST(X2_3) { - run_test (_this, "x2-3"); + run_test (_this, "x2-3", "au_2.oas.gz"); } TEST(X2_4) diff --git a/testdata/algo/deep_region_au3.gds b/testdata/algo/deep_region_au3.gds index e2e935ba88..406c175bce 100644 Binary files a/testdata/algo/deep_region_au3.gds and b/testdata/algo/deep_region_au3.gds differ diff --git a/testdata/algo/deep_region_au3b.gds b/testdata/algo/deep_region_au3b.gds index e741130cf5..e3f7a4493b 100644 Binary files a/testdata/algo/deep_region_au3b.gds and b/testdata/algo/deep_region_au3b.gds differ diff --git a/testdata/algo/flat_region_au3.gds b/testdata/algo/flat_region_au3.gds index 74fba6e4fa..77e4e30a11 100644 Binary files a/testdata/algo/flat_region_au3.gds and b/testdata/algo/flat_region_au3.gds differ diff --git a/testdata/algo/flat_region_au3b.gds b/testdata/algo/flat_region_au3b.gds index b6040526f4..28e9a43621 100644 Binary files a/testdata/algo/flat_region_au3b.gds and b/testdata/algo/flat_region_au3b.gds differ diff --git a/testdata/bool/special2_au1.oas b/testdata/bool/special2_au1.oas index a5f502f42c..0e47dce3a1 100644 Binary files a/testdata/bool/special2_au1.oas and b/testdata/bool/special2_au1.oas differ diff --git a/testdata/bool/special2_au1_tz.oas b/testdata/bool/special2_au1_tz.oas index 3290873a0a..cebd60d150 100644 Binary files a/testdata/bool/special2_au1_tz.oas and b/testdata/bool/special2_au1_tz.oas differ diff --git a/testdata/bool/special2_au4.oas b/testdata/bool/special2_au4.oas index e8580a4f14..13771eeeac 100644 Binary files a/testdata/bool/special2_au4.oas and b/testdata/bool/special2_au4.oas differ diff --git a/testdata/bool/special2_au5.oas b/testdata/bool/special2_au5.oas index 50fa6a864e..ea1f9fd1d8 100644 Binary files a/testdata/bool/special2_au5.oas and b/testdata/bool/special2_au5.oas differ diff --git a/testdata/bool/special2_au5_tz.oas b/testdata/bool/special2_au5_tz.oas index a374b17aa3..90ca8dc3c1 100644 Binary files a/testdata/bool/special2_au5_tz.oas and b/testdata/bool/special2_au5_tz.oas differ diff --git a/testdata/bool/special3_au1.oas b/testdata/bool/special3_au1.oas index 3f666f44ac..580886862a 100644 Binary files a/testdata/bool/special3_au1.oas and b/testdata/bool/special3_au1.oas differ diff --git a/testdata/bool/special3_au2.oas b/testdata/bool/special3_au2.oas index b0bcee8d71..9bdc9f3db0 100644 Binary files a/testdata/bool/special3_au2.oas and b/testdata/bool/special3_au2.oas differ diff --git a/testdata/bool/special3_au5.oas b/testdata/bool/special3_au5.oas index e4f0f1e8fd..f3b5a9976e 100644 Binary files a/testdata/bool/special3_au5.oas and b/testdata/bool/special3_au5.oas differ diff --git a/testdata/bool/twobool9_au1.oas b/testdata/bool/twobool9_au1.oas index 8b2353b7c0..e3f139eea3 100644 Binary files a/testdata/bool/twobool9_au1.oas and b/testdata/bool/twobool9_au1.oas differ diff --git a/testdata/bool/xor7_max_au1.oas b/testdata/bool/xor7_max_au1.oas index fce7269528..73aa257f66 100644 Binary files a/testdata/bool/xor7_max_au1.oas and b/testdata/bool/xor7_max_au1.oas differ diff --git a/testdata/bool/xor7_max_au2.oas b/testdata/bool/xor7_max_au2.oas index fce7269528..73aa257f66 100644 Binary files a/testdata/bool/xor7_max_au2.oas and b/testdata/bool/xor7_max_au2.oas differ