mirror of https://github.com/KLayout/klayout.git
WIP: lean recursive shape touch check
This commit is contained in:
parent
596080669d
commit
20f3733c58
|
|
@ -487,6 +487,41 @@ Cell::hierarchy_levels () const
|
|||
return m_hier_levels;
|
||||
}
|
||||
|
||||
static bool
|
||||
has_shapes_touching_impl (const db::Cell &cell, unsigned int layer, const db::Box &box)
|
||||
{
|
||||
if (! cell.shapes (layer).begin_touching (box, db::ShapeIterator::All).at_end ()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (db::Cell::touching_iterator i = cell.begin_touching (box); ! i.at_end (); ++i) {
|
||||
|
||||
for (db::CellInstArray::iterator ia = i->cell_inst ().begin_touching (box, db::box_convert<db::CellInst> (*cell.layout (), layer)); ! ia.at_end (); ++ia) {
|
||||
|
||||
db::Box cbox;
|
||||
if (i->is_complex ()) {
|
||||
cbox = i->complex_trans (*ia).inverted () * box;
|
||||
} else {
|
||||
cbox = (*ia).inverted () * box;
|
||||
}
|
||||
|
||||
if (has_shapes_touching_impl (cell.layout ()->cell (i->cell_index ()), layer, cbox)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Cell::has_shapes_touching (unsigned int layer, const db::Box &box) const
|
||||
{
|
||||
return has_shapes_touching_impl (*this, layer, box);
|
||||
}
|
||||
|
||||
void
|
||||
Cell::collect_caller_cells (std::set<cell_index_type> &callers) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -721,6 +721,11 @@ public:
|
|||
return shapes (layer).begin_touching (box, flags, prop_sel, inv_prop_sel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A quick, recursive test whether the cell has shapes touching the given box on the given layer
|
||||
*/
|
||||
bool has_shapes_touching (unsigned int layer, const db::Box &box) const;
|
||||
|
||||
/**
|
||||
* @brief Collect all calling cells (either calling this cell directly or indirectly)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1104,7 +1104,7 @@ printf("@@@ -> #%d\n", int(inst1->size()));
|
|||
db::Box ibox2 = tn2 * cell2.bbox (m_intruder_layer).enlarged (db::Vector (m_dist, m_dist));
|
||||
|
||||
db::Box cbox = ibox1 & ibox2;
|
||||
if (! cbox.empty () && ! db::RecursiveShapeIterator (*mp_subject_layout, cell1, m_subject_layer, safe_box_enlarged (tni1 * cbox, -1, -1), false).at_end ()) {
|
||||
if (! cbox.empty () && cell1.has_shapes_touching (m_subject_layer, safe_box_enlarged (tni1 * cbox, -1, -1))) {
|
||||
|
||||
db::ICplxTrans tn21 = tni1 * tn2;
|
||||
|
||||
|
|
@ -1151,14 +1151,14 @@ printf("@@@ -> #%d\n", int(inst1->size()));
|
|||
|
||||
const db::Cell &ic = mp_intruder_layout->cell (i->cell_index ());
|
||||
|
||||
for (db::CellInstArray::iterator ia = i->begin_touching (tbox2, mp_intruder_layout); ! ia.at_end (); ++ia) {
|
||||
for (db::CellInstArray::iterator ia = i->cell_inst ().begin_touching (tbox2, db::box_convert<db::CellInst> (*mp_intruder_layout, m_intruder_layer)); ! ia.at_end (); ++ia) {
|
||||
|
||||
db::ICplxTrans it = i->complex_trans (*ia);
|
||||
|
||||
db::Box ibox2 = tni2.inverted () * it * ic.bbox (m_intruder_layer).enlarged (db::Vector (m_dist, m_dist));
|
||||
db::Box ccbox = cbox & ibox2;
|
||||
|
||||
if (! ccbox.empty () && ! db::RecursiveShapeIterator (*mp_subject_layout, subject_cell, m_subject_layer, safe_box_enlarged (tni1 * ccbox, -1, -1), false).at_end ()) {
|
||||
if (! ccbox.empty ()) {
|
||||
collect_intruder_tree_interactions (subject_cell, ic, tni1, tn21 * it, ccbox, interactions);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1014,3 +1014,49 @@ TEST(6)
|
|||
|
||||
}
|
||||
|
||||
TEST(10_HasShapesTouching)
|
||||
{
|
||||
db::Layout ly;
|
||||
unsigned int l1 = ly.insert_layer (db::LayerProperties (1, 0));
|
||||
|
||||
db::Cell &a = ly.cell (ly.add_cell ("A"));
|
||||
|
||||
EXPECT_EQ (a.has_shapes_touching (l1, db::Box ()), false);
|
||||
|
||||
a.shapes (l1).insert (db::Box (-100, -100, 0, 0));
|
||||
|
||||
EXPECT_EQ (a.has_shapes_touching (l1, db::Box ()), false);
|
||||
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (0, 0, 100, 100)), true);
|
||||
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (0, 1, 100, 100)), false);
|
||||
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (0, -1, 100, 100)), true);
|
||||
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (-1, -1, -1, -1)), true);
|
||||
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (1, 1, 1, 1)), false);
|
||||
}
|
||||
|
||||
TEST(11_HasShapesTouchingWithHier)
|
||||
{
|
||||
db::Layout ly;
|
||||
unsigned int l1 = ly.insert_layer (db::LayerProperties (1, 0));
|
||||
unsigned int l2 = ly.insert_layer (db::LayerProperties (2, 0));
|
||||
|
||||
db::Cell &a = ly.cell (ly.add_cell ("A"));
|
||||
db::Cell &b = ly.cell (ly.add_cell ("B"));
|
||||
|
||||
a.insert (db::CellInstArray (b.cell_index (), db::Trans (db::Vector (100, 100)), db::Vector (0, 200), db::Vector (200, 0), 2, 2));
|
||||
|
||||
EXPECT_EQ (a.has_shapes_touching (l1, db::Box ()), false);
|
||||
EXPECT_EQ (a.has_shapes_touching (l2, db::Box ()), false);
|
||||
|
||||
b.shapes (l1).insert (db::Box (0, 0, 10, 10));
|
||||
|
||||
EXPECT_EQ (a.has_shapes_touching (l1, db::Box ()), false);
|
||||
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (0, 0, 100, 100)), true);
|
||||
EXPECT_EQ (a.has_shapes_touching (l2, db::Box (0, 0, 100, 100)), false);
|
||||
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (0, 0, 99, 100)), false);
|
||||
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (0, 0, 100, 99)), false);
|
||||
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (100, 100, 110, 110)), true);
|
||||
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (150, 150, 160, 160)), false);
|
||||
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (300, 300, 310, 310)), true);
|
||||
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (300, 100, 310, 110)), true);
|
||||
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (300, 400, 310, 410)), false);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue