This commit is contained in:
Matthias Köfferlein 2025-03-04 21:37:18 +01:00 committed by GitHub
commit d2f9a5b993
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 75 additions and 25 deletions

View File

@ -413,6 +413,8 @@ PolygonGenerator::begin_scanline (db::Coord y)
m_open_pos = m_open.begin ();
m_y = y;
m_prev_stitch_index = std::numeric_limits<size_t>::max ();
#ifdef DEBUG_POLYGON_GENERATOR
printf ("m_open=");
for (open_map_type::const_iterator o = m_open.begin (); o != m_open.end (); ++o) {
@ -823,27 +825,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<db::Coord>::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<db::Coord>::rounded (edge_xaty (eprev, m_y));
for (PGPolyContour::iterator i = ins; i > cprev.begin () + 1; --i) {
#if 1 // experimental
if (m_prev_stitch_index == iprev) {
db::Edge ecut (i[-2], i[-1]);
db::Coord xcut = db::coord_traits<db::Coord>::rounded (edge_xaty (db::Edge (i[-2], i[-1]), m_y));
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<db::Coord>::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;
}
--iii;
if (ii->y () >= m_y) {
db::Edge ecut (*iii, *ii);
db::Coord xcut = db::coord_traits<db::Coord>::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;
}
}
@ -867,6 +910,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 ());

View File

@ -183,6 +183,8 @@ private:
db::SimplePolygon m_spoly;
static bool ms_compress;
bool m_compress;
size_t m_prev_stitch_index;
std::list<db::Point>::iterator m_prev_stitch_ins;
void join_contours (db::Coord x);
void produce_poly (const PGPolyContour &c);

View File

@ -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

View File

@ -33,7 +33,7 @@
#include <stdlib.h>
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)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.