mirror of https://github.com/KLayout/klayout.git
A small, but sometimes effective optimization of DRC check functions: if a feature is entirely covered (with interaction distance) by a box, it is enough to check against the box
This commit is contained in:
parent
199cf1edfa
commit
3df88ae279
|
|
@ -232,6 +232,8 @@ check_local_operation_base<TS, TI>::compute_results (db::Layout *layout, db::Cel
|
||||||
bool take_all = edge_check.has_negative_edge_output () || intruders.empty ();
|
bool take_all = edge_check.has_negative_edge_output () || intruders.empty ();
|
||||||
|
|
||||||
db::Box common_box;
|
db::Box common_box;
|
||||||
|
bool subjects_are_fully_covered = false;
|
||||||
|
|
||||||
if (! take_all) {
|
if (! take_all) {
|
||||||
|
|
||||||
db::Vector e (edge_check.distance (), edge_check.distance ());
|
db::Vector e (edge_check.distance (), edge_check.distance ());
|
||||||
|
|
@ -241,14 +243,24 @@ check_local_operation_base<TS, TI>::compute_results (db::Layout *layout, db::Cel
|
||||||
subject_box += db::box_convert<TS> () (**i);
|
subject_box += db::box_convert<TS> () (**i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (edge_check.requires_different_layers ()) {
|
common_box = subject_box.enlarged (e);
|
||||||
db::Box intruder_box;
|
|
||||||
|
if (edge_check.requires_different_layers () && ! common_box.empty ()) {
|
||||||
|
|
||||||
|
subjects_are_fully_covered = false;
|
||||||
|
|
||||||
|
db::Box all_intruders_box;
|
||||||
|
|
||||||
for (auto i = intruders.begin (); i != intruders.end (); ++i) {
|
for (auto i = intruders.begin (); i != intruders.end (); ++i) {
|
||||||
intruder_box += db::box_convert<TI> () (**i);
|
db::Box intruder_box = db::box_convert<TI> () (**i);
|
||||||
|
if (! subjects_are_fully_covered && (*i)->is_box () && common_box.inside (intruder_box)) {
|
||||||
|
subjects_are_fully_covered = true;
|
||||||
|
}
|
||||||
|
all_intruders_box += intruder_box.enlarged (e);
|
||||||
}
|
}
|
||||||
common_box = subject_box.enlarged (e) & intruder_box.enlarged (e);
|
|
||||||
} else {
|
common_box &= all_intruders_box;
|
||||||
common_box = subject_box.enlarged (e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -306,6 +318,22 @@ check_local_operation_base<TS, TI>::compute_results (db::Layout *layout, db::Cel
|
||||||
|
|
||||||
// empty intruders
|
// empty intruders
|
||||||
|
|
||||||
|
} else if (subjects_are_fully_covered) {
|
||||||
|
|
||||||
|
// optimization: can use a single box for the intruders
|
||||||
|
|
||||||
|
n = 1;
|
||||||
|
|
||||||
|
db::Point ul = common_box.upper_left ();
|
||||||
|
db::Point lr = common_box.lower_right ();
|
||||||
|
|
||||||
|
poly_check.enter (db::Edge (common_box.p1 (), ul), n);
|
||||||
|
poly_check.enter (db::Edge (ul, common_box.p2 ()), n);
|
||||||
|
poly_check.enter (db::Edge (common_box.p2 (), lr), n);
|
||||||
|
poly_check.enter (db::Edge (lr, common_box.p1 ()), n);
|
||||||
|
|
||||||
|
n += 2;
|
||||||
|
|
||||||
} else if (! m_other_is_merged && (intruders.size () > 1 || ! (*intruders.begin ())->is_box ())) {
|
} else if (! m_other_is_merged && (intruders.size () > 1 || ! (*intruders.begin ())->is_box ())) {
|
||||||
|
|
||||||
// NOTE: this local merge is not necessarily giving the same results than a global merge before running
|
// NOTE: this local merge is not necessarily giving the same results than a global merge before running
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue