mirror of https://github.com/KLayout/klayout.git
Merge branch 'issue-1934-partial'
This commit is contained in:
commit
3a0778226e
|
|
@ -479,6 +479,9 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db:
|
||||||
{
|
{
|
||||||
checkpoint ();
|
checkpoint ();
|
||||||
|
|
||||||
|
// Viewport in current cell coordinate space (DBU)
|
||||||
|
db::Box viewport_box = (vp * db::CplxTrans (layout ().dbu ()) * t).inverted () * db::DBox (0, 0, view ()->viewport ().width (), view ()->viewport ().height ());
|
||||||
|
|
||||||
if (! m_context_layers.empty ()) {
|
if (! m_context_layers.empty ()) {
|
||||||
|
|
||||||
std::map<db::cell_index_type, bool>::const_iterator ctx = m_cells_with_context.find (cell.cell_index ());
|
std::map<db::cell_index_type, bool>::const_iterator ctx = m_cells_with_context.find (cell.cell_index ());
|
||||||
|
|
@ -517,7 +520,9 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db:
|
||||||
checkpoint ();
|
checkpoint ();
|
||||||
|
|
||||||
db::Box bbox;
|
db::Box bbox;
|
||||||
if (text_info () && shape->is_text ()) {
|
if (! view ()->text_visible () && shape->is_text ()) {
|
||||||
|
// ignore texts if the view does not show them
|
||||||
|
} else if (text_info () && shape->is_text ()) {
|
||||||
db::CplxTrans t_dbu = db::CplxTrans (layout ().dbu ()) * t;
|
db::CplxTrans t_dbu = db::CplxTrans (layout ().dbu ()) * t;
|
||||||
db::Text text;
|
db::Text text;
|
||||||
shape->text (text);
|
shape->text (text);
|
||||||
|
|
@ -569,32 +574,40 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db:
|
||||||
bool match = false;
|
bool match = false;
|
||||||
double d = std::numeric_limits<double>::max ();
|
double d = std::numeric_limits<double>::max ();
|
||||||
|
|
||||||
checkpoint ();
|
|
||||||
|
|
||||||
db::Point point (hit_box.center ());
|
db::Point point (hit_box.center ());
|
||||||
|
|
||||||
// in point mode, test the edges and use a "closest" criterion
|
// in point mode, test the edges and use a "closest" criterion
|
||||||
if (shape->is_polygon ()) {
|
if (shape->is_polygon ()) {
|
||||||
|
|
||||||
|
bool any_valid_edge = false;
|
||||||
for (db::Shape::polygon_edge_iterator e = shape->begin_edge (); ! e.at_end (); ++e) {
|
for (db::Shape::polygon_edge_iterator e = shape->begin_edge (); ! e.at_end (); ++e) {
|
||||||
test_edge (t, *e, d, match);
|
if ((*e).clipped (viewport_box).first) {
|
||||||
|
any_valid_edge = true;
|
||||||
|
test_edge (t, *e, d, match);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// test if inside the polygon
|
// test if inside the polygon
|
||||||
if (! match && inside_poly (shape->begin_edge (), point) >= 0) {
|
if (! match && any_valid_edge && inside_poly (shape->begin_edge (), point) >= 0) {
|
||||||
d = t.ctrans (poly_dist (shape->begin_edge (), point));
|
d = t.ctrans (poly_dist (shape->begin_edge (), point));
|
||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (shape->is_path ()) {
|
} else if (shape->is_path ()) {
|
||||||
|
|
||||||
|
bool any_valid_edge = false;
|
||||||
|
|
||||||
// test the "spine"
|
// test the "spine"
|
||||||
db::Shape::point_iterator pt = shape->begin_point ();
|
db::Shape::point_iterator pt = shape->begin_point ();
|
||||||
if (pt != shape->end_point ()) {
|
if (pt != shape->end_point ()) {
|
||||||
db::Point p (*pt);
|
db::Point p (*pt);
|
||||||
++pt;
|
++pt;
|
||||||
for (; pt != shape->end_point (); ++pt) {
|
for (; pt != shape->end_point (); ++pt) {
|
||||||
test_edge (t, db::Edge (p, *pt), d, match);
|
db::Edge e (p, *pt);
|
||||||
|
if (e.clipped (viewport_box).first) {
|
||||||
|
any_valid_edge = true;
|
||||||
|
test_edge (t, e, d, match);
|
||||||
|
}
|
||||||
p = *pt;
|
p = *pt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -603,16 +616,19 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db:
|
||||||
db::Polygon poly;
|
db::Polygon poly;
|
||||||
shape->polygon (poly);
|
shape->polygon (poly);
|
||||||
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
|
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
|
||||||
test_edge (t, *e, d, match);
|
if ((*e).clipped (viewport_box).first) {
|
||||||
|
any_valid_edge = true;
|
||||||
|
test_edge (t, *e, d, match);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// test if inside the polygon
|
// test if inside the polygon
|
||||||
if (! match && inside_poly (poly.begin_edge (), point) >= 0) {
|
if (! match && any_valid_edge && inside_poly (poly.begin_edge (), point) >= 0) {
|
||||||
d = t.ctrans (poly_dist (poly.begin_edge (), point));
|
d = t.ctrans (poly_dist (poly.begin_edge (), point));
|
||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (shape->is_box () || shape->is_point () || shape->is_text ()) {
|
} else if (shape->is_box () || shape->is_point () || (shape->is_text () && view ()->text_visible ())) {
|
||||||
|
|
||||||
db::Box box = shape->bbox ();
|
db::Box box = shape->bbox ();
|
||||||
if (text_info () && shape->is_text ()) {
|
if (text_info () && shape->is_text ()) {
|
||||||
|
|
@ -628,13 +644,18 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db:
|
||||||
match = true;
|
match = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
bool any_valid_edge = false;
|
||||||
|
|
||||||
// convert to polygon and test those edges
|
// convert to polygon and test those edges
|
||||||
db::Polygon poly (box);
|
db::Polygon poly (box);
|
||||||
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
|
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
|
||||||
test_edge (t, *e, d, match);
|
if ((*e).clipped (viewport_box).first) {
|
||||||
|
any_valid_edge = true;
|
||||||
|
test_edge (t, *e, d, match);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! match && box.contains (hit_box.center ())) {
|
if (! match && any_valid_edge && box.contains (hit_box.center ())) {
|
||||||
d = t.ctrans (poly_dist (poly.begin_edge (), point));
|
d = t.ctrans (poly_dist (poly.begin_edge (), point));
|
||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
|
|
@ -783,8 +804,13 @@ InstFinder::checkpoint ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
InstFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const db::Box & /*scan_box*/, const db::DCplxTrans & /*vp*/, const db::ICplxTrans &t, int level)
|
InstFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const db::Box & /*scan_box*/, const db::DCplxTrans &vp, const db::ICplxTrans &t, int level)
|
||||||
{
|
{
|
||||||
|
checkpoint ();
|
||||||
|
|
||||||
|
// Viewport in current cell coordinate space (DBU)
|
||||||
|
db::Box viewport_box = (vp * db::CplxTrans (layout ().dbu ()) * t).inverted () * db::DBox (0, 0, view ()->viewport ().width (), view ()->viewport ().height ());
|
||||||
|
|
||||||
if (! point_mode ()) {
|
if (! point_mode ()) {
|
||||||
|
|
||||||
++*mp_progress;
|
++*mp_progress;
|
||||||
|
|
@ -864,8 +890,6 @@ InstFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const d
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
checkpoint ();
|
|
||||||
|
|
||||||
// look for instances to check here ..
|
// look for instances to check here ..
|
||||||
db::Cell::touching_iterator inst = cell.begin_touching (search_box);
|
db::Cell::touching_iterator inst = cell.begin_touching (search_box);
|
||||||
while (! inst.at_end ()) {
|
while (! inst.at_end ()) {
|
||||||
|
|
@ -909,11 +933,16 @@ InstFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const d
|
||||||
// convert to polygon and test those edges
|
// convert to polygon and test those edges
|
||||||
db::Polygon poly (cell_inst.complex_trans (*p) * db::Polygon (ibox));
|
db::Polygon poly (cell_inst.complex_trans (*p) * db::Polygon (ibox));
|
||||||
|
|
||||||
|
bool any_valid_edge = false;
|
||||||
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
|
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
|
||||||
test_edge (t, *e, d, match);
|
// only consider edges that cut through the viewport
|
||||||
|
if ((*e).clipped (viewport_box).first) {
|
||||||
|
any_valid_edge = true;
|
||||||
|
test_edge (t, *e, d, match);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! match && db::inside_poly (poly.begin_edge (), search_box.center ())) {
|
if (! match && any_valid_edge && db::inside_poly (poly.begin_edge (), search_box.center ())) {
|
||||||
d = t.ctrans (poly_dist (poly.begin_edge (), search_box.center ()));
|
d = t.ctrans (poly_dist (poly.begin_edge (), search_box.center ()));
|
||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4079,6 +4079,9 @@ LayoutViewBase::transform (const db::DCplxTrans &tr)
|
||||||
void
|
void
|
||||||
LayoutViewBase::cancel_edits ()
|
LayoutViewBase::cancel_edits ()
|
||||||
{
|
{
|
||||||
|
// clear any messages
|
||||||
|
message ();
|
||||||
|
|
||||||
// the move service takes a special role here as it manages the
|
// the move service takes a special role here as it manages the
|
||||||
// transaction for the collective move operation.
|
// transaction for the collective move operation.
|
||||||
mp_move_service->cancel ();
|
mp_move_service->cancel ();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue