diff --git a/src/laybasic/laybasic/layFinder.cc b/src/laybasic/laybasic/layFinder.cc index 0b3303d05..b5e1c5df5 100644 --- a/src/laybasic/laybasic/layFinder.cc +++ b/src/laybasic/laybasic/layFinder.cc @@ -479,6 +479,9 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db: { 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 ()) { std::map::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 (); 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::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; double d = std::numeric_limits::max (); - checkpoint (); - db::Point point (hit_box.center ()); // in point mode, test the edges and use a "closest" criterion if (shape->is_polygon ()) { + bool any_valid_edge = false; 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 - 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)); match = true; } } else if (shape->is_path ()) { + bool any_valid_edge = false; + // test the "spine" - db::Shape::point_iterator pt = shape->begin_point (); + db::Shape::point_iterator pt = shape->begin_point (); if (pt != shape->end_point ()) { db::Point p (*pt); ++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; } } @@ -603,16 +616,19 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db: db::Polygon poly; shape->polygon (poly); 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 - 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)); 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 (); 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; } else { + bool any_valid_edge = false; + // convert to polygon and test those edges db::Polygon poly (box); 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)); match = true; } @@ -783,8 +804,13 @@ InstFinder::checkpoint () } 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 ()) { ++*mp_progress; @@ -864,8 +890,6 @@ InstFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const d } else { - checkpoint (); - // look for instances to check here .. db::Cell::touching_iterator inst = cell.begin_touching (search_box); 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 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) { - 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 ())); match = true; } diff --git a/src/laybasic/laybasic/layLayoutViewBase.cc b/src/laybasic/laybasic/layLayoutViewBase.cc index aab012789..19e6ab7b0 100644 --- a/src/laybasic/laybasic/layLayoutViewBase.cc +++ b/src/laybasic/laybasic/layLayoutViewBase.cc @@ -4079,6 +4079,9 @@ LayoutViewBase::transform (const db::DCplxTrans &tr) void LayoutViewBase::cancel_edits () { + // clear any messages + message (); + // the move service takes a special role here as it manages the // transaction for the collective move operation. mp_move_service->cancel ();