diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index 9635b9bde..80407fdfd 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -302,6 +302,30 @@ typename local_cluster::shape_iterator local_cluster::begin (unsigned int } } +template +bool +local_cluster::interacts (const db::Cell &cell, const db::ICplxTrans &trans, const Connectivity &conn) const +{ + db::box_convert bc; + + for (typename std::map::const_iterator s = m_shapes.begin (); s != m_shapes.end (); ++s) { + + db::Box box; + + Connectivity::layer_iterator le = conn.end_connected (s->first); + for (Connectivity::layer_iterator l = conn.begin_connected (s->first); l != le; ++l) { + box += cell.bbox (*l); + } + + if (! box.empty () && ! s->second.begin_touching (box.transformed (trans), bc).at_end ()) { + return true; + } + + } + + return false; +} + template bool local_cluster::interacts (const local_cluster &other, const db::ICplxTrans &trans, const Connectivity &conn) const @@ -970,14 +994,23 @@ private: box_type b1 = c1.bbox (); box_type bb2 = (*mp_cbc) (i2.cell_index ()); - box_type b2 = i2.cell_inst ().bbox (*mp_cbc).transformed (t2); - if (! b1.touches (b2)) { + db::ICplxTrans t2i = t2 * i2.complex_trans (); + const db::Cell &cell2 = mp_layout->cell (i2.cell_index ()); + + box_type b2 = cell2.bbox ().transformed (t2i); + + if (! b1.touches (b2) || ! c1.interacts (cell2, t2i, *mp_conn)) { return; } box_type common = b1 & b2; + std::vector pp2; + pp2.reserve (p2.size () + 1); + pp2.insert (pp2.end (), p2.begin (), p2.end ()); + pp2.push_back (db::InstElement ()); + for (db::CellInstArray::iterator ii2 = i2.begin_touching (common.transformed (t2.inverted ()), mp_layout); ! ii2.at_end (); ++ii2) { db::ICplxTrans tt2 = t2 * i2.complex_trans (*ii2); @@ -985,15 +1018,10 @@ private: if (b1.touches (ib2)) { - std::vector pp2; - pp2.reserve (p2.size () + 1); - pp2.insert (pp2.end (), p2.begin (), p2.end ()); - pp2.push_back (db::InstElement (i2, ii2)); - + pp2.back () = db::InstElement (i2, ii2); add_single_pair (c1, i2.cell_index (), pp2, tt2); // dive into cell of ii2 - const db::Cell &cell2 = mp_layout->cell (i2.cell_index ()); for (db::Cell::touching_iterator jj2 = cell2.begin_touching (common.transformed (tt2.inverted ())); ! jj2.at_end (); ++jj2) { add_pair (c1, *jj2, pp2, tt2); } @@ -1402,7 +1430,9 @@ connected_clusters & hier_clusters::clusters_per_cell (db::cell_index_type cell_index) { typename std::map >::iterator c = m_per_cell_clusters.find (cell_index); - tl_assert (c != m_per_cell_clusters.end ()); + if (c == m_per_cell_clusters.end ()) { + c = m_per_cell_clusters.insert (std::make_pair (cell_index, connected_clusters ())).first; + } return c->second; } diff --git a/src/db/db/dbHierNetworkProcessor.h b/src/db/db/dbHierNetworkProcessor.h index 21b3de313..d65d4c5f7 100644 --- a/src/db/db/dbHierNetworkProcessor.h +++ b/src/db/db/dbHierNetworkProcessor.h @@ -184,6 +184,14 @@ public: */ bool interacts (const local_cluster &other, const db::ICplxTrans &trans, const Connectivity &conn) const; + /** + * @brief Tests whether this cluster interacts with the given cell + * + * "trans" is the transformation which is applied to the cell before + * the test. + */ + bool interacts (const db::Cell &cell, const db::ICplxTrans &trans, const Connectivity &conn) const; + /** * @brief Gets the bounding box of this cluster */