selecting shapes only if edges are visible too

This commit is contained in:
Matthias Koefferlein 2024-11-30 21:45:41 +01:00
parent d361030048
commit 2c6eca04d6
1 changed files with 31 additions and 12 deletions

View File

@ -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<db::cell_index_type, bool>::const_iterator ctx = m_cells_with_context.find (cell.cell_index ());
@ -569,32 +572,40 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db:
bool match = false;
double d = std::numeric_limits<double>::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,11 +614,14 @@ 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;
}
@ -628,13 +642,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;
}
@ -785,6 +804,8 @@ 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)
{
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 ());
@ -867,8 +888,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 ()) {