mirror of https://github.com/KLayout/klayout.git
Fixed #72 (Edges/Region NOT issue)
This commit is contained in:
parent
432a8dddb8
commit
808159bcab
|
|
@ -1014,7 +1014,20 @@ EdgeProcessor::clear ()
|
|||
mp_cpvector->clear ();
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
add_hparallel_cutpoints (WorkEdge &e1, WorkEdge &e2, std::vector <CutPoints> &cutpoints)
|
||||
{
|
||||
db::Coord e1_xmin = std::min (e1.x1 (), e1.x2 ());
|
||||
db::Coord e1_xmax = std::max (e1.x1 (), e1.x2 ());
|
||||
if (e2.x1 () > e1_xmin && e2.x1 () < e1_xmax) {
|
||||
e1.make_cutpoints (cutpoints)->add (e2.p1 (), &cutpoints, false);
|
||||
}
|
||||
if (e2.x2 () > e1_xmin && e2.x2 () < e1_xmax) {
|
||||
e1.make_cutpoints (cutpoints)->add (e2.p2 (), &cutpoints, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_intersections_per_band_90 (std::vector <CutPoints> &cutpoints, std::vector <WorkEdge>::iterator current, std::vector <WorkEdge>::iterator future, db::Coord y, db::Coord yy, bool with_h)
|
||||
{
|
||||
std::sort (current, future, edge_xmin_compare<db::Coord> ());
|
||||
|
|
@ -1066,22 +1079,34 @@ get_intersections_per_band_90 (std::vector <CutPoints> &cutpoints, std::vector <
|
|||
|
||||
if (c2->dy () == 0) {
|
||||
|
||||
if ((with_h || c1->dy () != 0) && c1 < c2 && c1->p1 () != c2->p1 () && c1->p2 () != c2->p1 () &&
|
||||
c1->p1 () != c2->p2 () && c1->p2 () != c2->p2 ()) {
|
||||
if ((with_h || c1->dy () != 0) && c1 < c2) {
|
||||
|
||||
std::pair <bool, db::Point> cp = c1->intersect_point (*c2);
|
||||
if (cp.first) {
|
||||
|
||||
// add a cut point to c1 and c2 (c2 only if necessary)
|
||||
c1->make_cutpoints (cutpoints)->add (cp.second, &cutpoints, true);
|
||||
if (with_h) {
|
||||
c2->make_cutpoints (cutpoints)->add (cp.second, &cutpoints, true);
|
||||
if (c1->dy () == 0) {
|
||||
|
||||
// parallel horizontal edges: produce the end points of each other edge as cutpoints
|
||||
if (c1->p1 ().y () == c2->p1 ().y ()) {
|
||||
add_hparallel_cutpoints (*c1, *c2, cutpoints);
|
||||
add_hparallel_cutpoints (*c2, *c1, cutpoints);
|
||||
}
|
||||
|
||||
} else if (c1->p1 () != c2->p1 () && c1->p2 () != c2->p1 () &&
|
||||
c1->p1 () != c2->p2 () && c1->p2 () != c2->p2 ()) {
|
||||
|
||||
std::pair <bool, db::Point> cp = c1->intersect_point (*c2);
|
||||
if (cp.first) {
|
||||
|
||||
// add a cut point to c1 and c2 (c2 only if necessary)
|
||||
c1->make_cutpoints (cutpoints)->add (cp.second, &cutpoints, true);
|
||||
if (with_h) {
|
||||
c2->make_cutpoints (cutpoints)->add (cp.second, &cutpoints, true);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_EDGE_PROCESSOR
|
||||
printf ("intersection point %s between %s and %s (1).\n", cp.second.to_string ().c_str (), c1->to_string ().c_str (), c2->to_string ().c_str ());
|
||||
printf ("intersection point %s between %s and %s (1).\n", cp.second.to_string ().c_str (), c1->to_string ().c_str (), c2->to_string ().c_str ());
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1287,51 +1312,63 @@ get_intersections_per_band_any (std::vector <CutPoints> &cutpoints, std::vector
|
|||
|
||||
if (c2->dy () == 0) {
|
||||
|
||||
if ((with_h || c1->dy () != 0) && c1 < c2 && c1->p1 () != c2->p1 () && c1->p2 () != c2->p1 () &&
|
||||
c1->p1 () != c2->p2 () && c1->p2 () != c2->p2 ()) {
|
||||
if ((with_h || c1->dy () != 0) && c1 < c2) {
|
||||
|
||||
std::pair <bool, db::Point> cp = safe_intersect_point (*c1, *c2);
|
||||
if (cp.first) {
|
||||
if (c1->dy () == 0) {
|
||||
|
||||
bool on_edge1 = is_point_on_exact (*c1, cp.second);
|
||||
|
||||
// add a cut point to c1 and c2 (points not on the edge give strong attractors)
|
||||
c1->make_cutpoints (cutpoints)->add (cp.second, &cutpoints, !on_edge1);
|
||||
if (with_h) {
|
||||
c2->make_cutpoints (cutpoints)->add (cp.second, &cutpoints, false);
|
||||
// parallel horizontal edges: produce the end points of each other edge as cutpoints
|
||||
if (c1->p1 ().y () == c2->p1 ().y ()) {
|
||||
add_hparallel_cutpoints (*c1, *c2, cutpoints);
|
||||
add_hparallel_cutpoints (*c2, *c1, cutpoints);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_EDGE_PROCESSOR
|
||||
if (on_edge1) {
|
||||
printf ("weak intersection point %s between %s and %s.\n", cp.second.to_string ().c_str (), c1->to_string ().c_str (), c2->to_string ().c_str ());
|
||||
} else {
|
||||
printf ("intersection point %s between %s and %s.\n", cp.second.to_string ().c_str (), c1->to_string ().c_str (), c2->to_string ().c_str ());
|
||||
}
|
||||
#endif
|
||||
} else if (c1->p1 () != c2->p1 () && c1->p2 () != c2->p1 () &&
|
||||
c1->p1 () != c2->p2 () && c1->p2 () != c2->p2 ()) {
|
||||
|
||||
// The new cutpoint must be inserted into other edges as well.
|
||||
// If the cutpoint is exactly on the edge and there is just one other edge
|
||||
// the cutpoint will be a weak attractor - that is an optional cutpoint.
|
||||
// In that case we can skip the cutpoint because no related edge will move.
|
||||
ip_weak.clear ();
|
||||
for (std::vector <WorkEdge>::iterator cc = c; cc != f; ++cc) {
|
||||
if ((with_h || cc->dy () != 0) && cc != c1 && cc != c2 && is_point_on_fuzzy (*cc, cp.second)) {
|
||||
ip_weak.push_back (&*cc);
|
||||
std::pair <bool, db::Point> cp = safe_intersect_point (*c1, *c2);
|
||||
if (cp.first) {
|
||||
|
||||
bool on_edge1 = is_point_on_exact (*c1, cp.second);
|
||||
|
||||
// add a cut point to c1 and c2 (points not on the edge give strong attractors)
|
||||
c1->make_cutpoints (cutpoints)->add (cp.second, &cutpoints, !on_edge1);
|
||||
if (with_h) {
|
||||
c2->make_cutpoints (cutpoints)->add (cp.second, &cutpoints, false);
|
||||
}
|
||||
}
|
||||
for (std::vector <WorkEdge *>::iterator icc = ip_weak.begin (); icc != ip_weak.end (); ++icc) {
|
||||
if (ip_weak.size () > 1 || !on_edge1) {
|
||||
(*icc)->make_cutpoints (cutpoints)->add (cp.second, &cutpoints, true);
|
||||
|
||||
#ifdef DEBUG_EDGE_PROCESSOR
|
||||
printf ("intersection point %s gives cutpoint in %s.\n", cp.second.to_string ().c_str (), (*icc)->to_string ().c_str ());
|
||||
#endif
|
||||
if (on_edge1) {
|
||||
printf ("weak intersection point %s between %s and %s.\n", cp.second.to_string ().c_str (), c1->to_string ().c_str (), c2->to_string ().c_str ());
|
||||
} else {
|
||||
CutPoints *cpp = (*icc)->make_cutpoints (cutpoints);
|
||||
cpp->add_attractor (cp.second, (*icc)->data - 1);
|
||||
#ifdef DEBUG_EDGE_PROCESSOR
|
||||
printf ("intersection point %s gives weak attractor in %s.\n", cp.second.to_string ().c_str (), (*icc)->to_string ().c_str ());
|
||||
#endif
|
||||
printf ("intersection point %s between %s and %s.\n", cp.second.to_string ().c_str (), c1->to_string ().c_str (), c2->to_string ().c_str ());
|
||||
}
|
||||
#endif
|
||||
|
||||
// The new cutpoint must be inserted into other edges as well.
|
||||
// If the cutpoint is exactly on the edge and there is just one other edge
|
||||
// the cutpoint will be a weak attractor - that is an optional cutpoint.
|
||||
// In that case we can skip the cutpoint because no related edge will move.
|
||||
ip_weak.clear ();
|
||||
for (std::vector <WorkEdge>::iterator cc = c; cc != f; ++cc) {
|
||||
if ((with_h || cc->dy () != 0) && cc != c1 && cc != c2 && is_point_on_fuzzy (*cc, cp.second)) {
|
||||
ip_weak.push_back (&*cc);
|
||||
}
|
||||
}
|
||||
for (std::vector <WorkEdge *>::iterator icc = ip_weak.begin (); icc != ip_weak.end (); ++icc) {
|
||||
if (ip_weak.size () > 1 || !on_edge1) {
|
||||
(*icc)->make_cutpoints (cutpoints)->add (cp.second, &cutpoints, true);
|
||||
#ifdef DEBUG_EDGE_PROCESSOR
|
||||
printf ("intersection point %s gives cutpoint in %s.\n", cp.second.to_string ().c_str (), (*icc)->to_string ().c_str ());
|
||||
#endif
|
||||
} else {
|
||||
CutPoints *cpp = (*icc)->make_cutpoints (cutpoints);
|
||||
cpp->add_attractor (cp.second, (*icc)->data - 1);
|
||||
#ifdef DEBUG_EDGE_PROCESSOR
|
||||
printf ("intersection point %s gives weak attractor in %s.\n", cp.second.to_string ().c_str (), (*icc)->to_string ().c_str ());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -820,3 +820,58 @@ TEST(22)
|
|||
EXPECT_EQ ((e & ee).to_string (), "(400,0;-2000,0);(500,-174;400,0);(1000,0;900,-173);(4000,0;1000,0)");
|
||||
}
|
||||
|
||||
// GitHub issue #72 (Edges/Region NOT issue)
|
||||
TEST(23)
|
||||
{
|
||||
db::Edges e;
|
||||
e.insert (db::Edge (0, 0, 0, 1000));
|
||||
e.insert (db::Edge (0, 1000, 3000, 1000));
|
||||
e.insert (db::Edge (3000, 1000, 3000, 0));
|
||||
e.insert (db::Edge (3000, 0, 0, 0));
|
||||
|
||||
db::Region r;
|
||||
r.insert (db::Box (1000, -1000, 2000, 0));
|
||||
r.insert (db::Box (1000, 1000, 2000, 2000));
|
||||
|
||||
EXPECT_EQ ((e - r).to_string (), "(0,0;0,1000);(1000,0;0,0);(3000,0;2000,0);(3000,1000;3000,0);(0,1000;1000,1000);(2000,1000;3000,1000)");
|
||||
|
||||
r.clear ();
|
||||
r.insert (db::Box (1000, -1000, 2000, 2000));
|
||||
|
||||
EXPECT_EQ ((e - r).to_string (), "(0,0;0,1000);(1000,0;0,0);(3000,0;2000,0);(3000,1000;3000,0);(0,1000;1000,1000);(2000,1000;3000,1000)");
|
||||
|
||||
e.clear ();
|
||||
e.insert (db::Edge (0, 0, 100, 1000));
|
||||
e.insert (db::Edge (100, 1000, 3100, 1000));
|
||||
e.insert (db::Edge (3100, 1000, 3000, 0));
|
||||
e.insert (db::Edge (3000, 0, 0, 0));
|
||||
|
||||
r.clear ();
|
||||
r.insert (db::Box (1000, -1000, 2000, 0));
|
||||
r.insert (db::Box (1000, 1000, 2000, 2000));
|
||||
|
||||
EXPECT_EQ ((e - r).to_string (), "(0,0;100,1000);(1000,0;0,0);(3000,0;2000,0);(3100,1000;3000,0);(100,1000;1000,1000);(2000,1000;3100,1000)");
|
||||
|
||||
r.clear ();
|
||||
r.insert (db::Box (1000, -1000, 2000, 2000));
|
||||
|
||||
EXPECT_EQ ((e - r).to_string (), "(0,0;100,1000);(1000,0;0,0);(3000,0;2000,0);(3100,1000;3000,0);(100,1000;1000,1000);(2000,1000;3100,1000)");
|
||||
|
||||
e.clear ();
|
||||
e.insert (db::Edge (0, 0, 1000, 0));
|
||||
e.insert (db::Edge (1000, 0, 1000, 3000));
|
||||
e.insert (db::Edge (1000, 3000, 0, 3000));
|
||||
e.insert (db::Edge (0, 3000, 0, 0));
|
||||
|
||||
r.clear ();
|
||||
r.insert (db::Box (-1000, 1000, 0, 2000));
|
||||
r.insert (db::Box (1000, 1000, 2000, 2000));
|
||||
|
||||
EXPECT_EQ ((e - r).to_string (), "(0,1000;0,0);(0,0;1000,0);(1000,0;1000,1000);(0,3000;0,2000);(1000,2000;1000,3000);(1000,3000;0,3000)");
|
||||
|
||||
r.clear ();
|
||||
r.insert (db::Box (-1000, 1000, 2000, 2000));
|
||||
|
||||
EXPECT_EQ ((e - r).to_string (), "(0,1000;0,0);(0,0;1000,0);(1000,0;1000,1000);(0,3000;0,2000);(1000,2000;1000,3000);(1000,3000;0,3000)");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue