mirror of https://github.com/KLayout/klayout.git
First bug fixes
* Only check for layers in the selected stack - this avoids problems with "masking" pin shapes for example * Use shape transformation for shapes inside hierarchy
This commit is contained in:
parent
a957386291
commit
fc4a8b92b0
|
|
@ -762,9 +762,9 @@ PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, co
|
||||||
{
|
{
|
||||||
if (! point_mode ()) {
|
if (! point_mode ()) {
|
||||||
|
|
||||||
for (std::vector<int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
for (std::vector<unsigned int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
||||||
|
|
||||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (scan_box))) {
|
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox (*l).touches (scan_box))) {
|
||||||
|
|
||||||
checkpoint ();
|
checkpoint ();
|
||||||
|
|
||||||
|
|
@ -897,9 +897,9 @@ PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, co
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
for (std::vector<int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
for (std::vector<unsigned int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
||||||
|
|
||||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (hit_box))) {
|
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox (*l).touches (hit_box))) {
|
||||||
|
|
||||||
checkpoint ();
|
checkpoint ();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ Finder::closer (double d)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Finder::start (lay::LayoutViewBase *view, unsigned int cv_index, const std::vector<db::DCplxTrans> &trans, const db::DBox ®ion, const db::DBox &scan_region, int min_level, int max_level, const std::vector<int> &layers)
|
Finder::start (lay::LayoutViewBase *view, unsigned int cv_index, const std::vector<db::DCplxTrans> &trans, const db::DBox ®ion, const db::DBox &scan_region, int min_level, int max_level, const std::vector<unsigned int> &layers)
|
||||||
{
|
{
|
||||||
const lay::CellView &cv = view->cellview (cv_index);
|
const lay::CellView &cv = view->cellview (cv_index);
|
||||||
|
|
||||||
|
|
@ -100,8 +100,8 @@ Finder::start (lay::LayoutViewBase *view, unsigned int cv_index, const std::vect
|
||||||
|
|
||||||
if (layers.size () == 1) {
|
if (layers.size () == 1) {
|
||||||
|
|
||||||
m_box_convert = db::box_convert <db::CellInst, false> (*mp_layout, (unsigned int) layers [0]);
|
m_box_convert = db::box_convert <db::CellInst, false> (*mp_layout, layers [0]);
|
||||||
m_cell_box_convert = db::box_convert <db::Cell, false> ((unsigned int) layers [0]);
|
m_cell_box_convert = db::box_convert <db::Cell, false> (layers [0]);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
@ -202,7 +202,7 @@ Finder::do_find (const db::Cell &cell, int level, const db::DCplxTrans &vp, cons
|
||||||
if (level <= m_max_level /*take level of cell itself*/
|
if (level <= m_max_level /*take level of cell itself*/
|
||||||
&& cell.is_proxy ()
|
&& cell.is_proxy ()
|
||||||
&& m_layers.size () == 1
|
&& m_layers.size () == 1
|
||||||
&& (unsigned int) m_layers [0] == mp_layout->guiding_shape_layer ()) {
|
&& m_layers [0] == mp_layout->guiding_shape_layer ()) {
|
||||||
|
|
||||||
// when looking at the guiding shape layer, we can visit this cell as well allowing to find the guiding shapes
|
// when looking at the guiding shape layer, we can visit this cell as well allowing to find the guiding shapes
|
||||||
|
|
||||||
|
|
@ -339,7 +339,7 @@ ShapeFinder::find (LayoutViewBase *view, const db::DBox ®ion_mu)
|
||||||
|
|
||||||
std::sort (lprops.begin (), lprops.end (), LPContextCompareOp ());
|
std::sort (lprops.begin (), lprops.end (), LPContextCompareOp ());
|
||||||
|
|
||||||
std::vector<int> layers;
|
std::vector<unsigned int> layers;
|
||||||
for (std::vector<lay::LayerPropertiesConstIterator>::const_iterator llp = lprops.begin (); llp != lprops.end (); ) {
|
for (std::vector<lay::LayerPropertiesConstIterator>::const_iterator llp = lprops.begin (); llp != lprops.end (); ) {
|
||||||
|
|
||||||
layers.clear ();
|
layers.clear ();
|
||||||
|
|
@ -347,7 +347,10 @@ ShapeFinder::find (LayoutViewBase *view, const db::DBox ®ion_mu)
|
||||||
lay::LayerPropertiesConstIterator lp0 = *llp;
|
lay::LayerPropertiesConstIterator lp0 = *llp;
|
||||||
LPContextEqualOp eq;
|
LPContextEqualOp eq;
|
||||||
do {
|
do {
|
||||||
layers.push_back ((*llp)->layer_index ());
|
int li = (*llp)->layer_index ();
|
||||||
|
if (li >= 0) {
|
||||||
|
layers.push_back ((unsigned int) li);
|
||||||
|
}
|
||||||
++llp;
|
++llp;
|
||||||
} while (llp != lprops.end () && eq(lp0, *llp));
|
} while (llp != lprops.end () && eq(lp0, *llp));
|
||||||
|
|
||||||
|
|
@ -398,16 +401,19 @@ ShapeFinder::find (lay::LayoutViewBase *view, const lay::LayerProperties &lprops
|
||||||
lay::TextInfo text_info (view);
|
lay::TextInfo text_info (view);
|
||||||
mp_text_info = (m_flags & db::ShapeIterator::Texts) != 0 ? &text_info : 0;
|
mp_text_info = (m_flags & db::ShapeIterator::Texts) != 0 ? &text_info : 0;
|
||||||
|
|
||||||
std::vector<int> layers;
|
std::vector<unsigned int> layers;
|
||||||
layers.push_back (lprops.layer_index ());
|
int li = lprops.layer_index ();
|
||||||
|
if (li >= 0) {
|
||||||
|
layers.push_back ((unsigned int) li);
|
||||||
|
}
|
||||||
bool result = find_internal (view, lprops.cellview_index (), &lprops.prop_sel (), lprops.inverse_prop_sel (), lprops.hier_levels (), lprops.trans (), layers, region_mu);
|
bool result = find_internal (view, lprops.cellview_index (), &lprops.prop_sel (), lprops.inverse_prop_sel (), lprops.hier_levels (), lprops.trans (), layers, region_mu);
|
||||||
|
|
||||||
mp_progress = 0;
|
mp_progress = 0;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ShapeFinder::find_internal (lay::LayoutViewBase *view, unsigned int cv_index, const std::set<db::properties_id_type> *prop_sel, bool inv_prop_sel, const lay::HierarchyLevelSelection &hier_sel, const std::vector<db::DCplxTrans> &trans_mu, const std::vector<int> &layers, const db::DBox ®ion_mu)
|
ShapeFinder::find_internal (lay::LayoutViewBase *view, unsigned int cv_index, const std::set<db::properties_id_type> *prop_sel, bool inv_prop_sel, const lay::HierarchyLevelSelection &hier_sel, const std::vector<db::DCplxTrans> &trans_mu, const std::vector<unsigned int> &layers, const db::DBox ®ion_mu)
|
||||||
{
|
{
|
||||||
m_cv_index = cv_index;
|
m_cv_index = cv_index;
|
||||||
|
|
||||||
|
|
@ -511,13 +517,13 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db:
|
||||||
|
|
||||||
if (! point_mode ()) {
|
if (! point_mode ()) {
|
||||||
|
|
||||||
for (std::vector<int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
for (std::vector<unsigned int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
||||||
|
|
||||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (scan_box))) {
|
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox (*l).touches (scan_box))) {
|
||||||
|
|
||||||
checkpoint ();
|
checkpoint ();
|
||||||
|
|
||||||
const db::Shapes &shapes = cell.shapes ((unsigned int) *l);
|
const db::Shapes &shapes = cell.shapes (*l);
|
||||||
|
|
||||||
db::ShapeIterator shape = shapes.begin_touching (scan_box, m_flags, mp_prop_sel, m_inv_prop_sel);
|
db::ShapeIterator shape = shapes.begin_touching (scan_box, m_flags, mp_prop_sel, m_inv_prop_sel);
|
||||||
while (! shape.at_end ()) {
|
while (! shape.at_end ()) {
|
||||||
|
|
@ -563,9 +569,9 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db:
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
for (std::vector<int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
for (std::vector<unsigned int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
||||||
|
|
||||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (scan_box))) {
|
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox (*l).touches (scan_box))) {
|
||||||
|
|
||||||
checkpoint ();
|
checkpoint ();
|
||||||
|
|
||||||
|
|
@ -793,7 +799,7 @@ InstFinder::find_internal (LayoutViewBase *view, unsigned int cv_index, const db
|
||||||
try {
|
try {
|
||||||
std::vector<db::DCplxTrans> tv;
|
std::vector<db::DCplxTrans> tv;
|
||||||
tv.push_back (trans_mu);
|
tv.push_back (trans_mu);
|
||||||
start (view, cv_index, tv, region_mu, region_mu, view->get_min_hier_levels (), view->get_max_hier_levels (), std::vector<int> ());
|
start (view, cv_index, tv, region_mu, region_mu, view->get_min_hier_levels (), view->get_max_hier_levels (), std::vector<unsigned int> ());
|
||||||
} catch (StopException) {
|
} catch (StopException) {
|
||||||
// ..
|
// ..
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const std::vector<int> &layers () const
|
const std::vector<unsigned int> &layers () const
|
||||||
{
|
{
|
||||||
return m_layers;
|
return m_layers;
|
||||||
}
|
}
|
||||||
|
|
@ -183,7 +183,7 @@ protected:
|
||||||
* @param max_level The maximum hierarchy level to check
|
* @param max_level The maximum hierarchy level to check
|
||||||
* @param layers A set of layers to check
|
* @param layers A set of layers to check
|
||||||
*/
|
*/
|
||||||
void start (LayoutViewBase *view, unsigned int cv_index, const std::vector<db::DCplxTrans> &trans, const db::DBox ®ion, const db::DBox &scan_region, int min_level, int max_level, const std::vector<int> &layers = std::vector<int> ());
|
void start (LayoutViewBase *view, unsigned int cv_index, const std::vector<db::DCplxTrans> &trans, const db::DBox ®ion, const db::DBox &scan_region, int min_level, int max_level, const std::vector<unsigned int> &layers = std::vector<unsigned int> ());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Provide a basic edge test facility
|
* @brief Provide a basic edge test facility
|
||||||
|
|
@ -232,7 +232,7 @@ private:
|
||||||
unsigned int m_cv_index;
|
unsigned int m_cv_index;
|
||||||
db::Box m_region;
|
db::Box m_region;
|
||||||
db::Box m_scan_region;
|
db::Box m_scan_region;
|
||||||
std::vector<int> m_layers;
|
std::vector<unsigned int> m_layers;
|
||||||
double m_distance;
|
double m_distance;
|
||||||
bool m_point_mode;
|
bool m_point_mode;
|
||||||
bool m_catch_all;
|
bool m_catch_all;
|
||||||
|
|
@ -267,8 +267,8 @@ public:
|
||||||
*/
|
*/
|
||||||
ShapeFinder (bool point_mode, bool top_level_sel, db::ShapeIterator::flags_type flags, const std::set<lay::ObjectInstPath> *excludes = 0, bool capture_all_shapes = false);
|
ShapeFinder (bool point_mode, bool top_level_sel, db::ShapeIterator::flags_type flags, const std::set<lay::ObjectInstPath> *excludes = 0, bool capture_all_shapes = false);
|
||||||
|
|
||||||
bool find (LayoutViewBase *view, const lay::LayerProperties &lprops, const db::DBox ®ion_mu);
|
bool find (lay::LayoutViewBase *view, const lay::LayerProperties &lprops, const db::DBox ®ion_mu);
|
||||||
bool find (LayoutViewBase *view, const db::DBox ®ion_mu);
|
bool find (lay::LayoutViewBase *view, const db::DBox ®ion_mu);
|
||||||
|
|
||||||
iterator begin () const
|
iterator begin () const
|
||||||
{
|
{
|
||||||
|
|
@ -327,7 +327,7 @@ private:
|
||||||
bool inv_prop_sel,
|
bool inv_prop_sel,
|
||||||
const lay::HierarchyLevelSelection &hier_sel,
|
const lay::HierarchyLevelSelection &hier_sel,
|
||||||
const std::vector<db::DCplxTrans> &trans_mu,
|
const std::vector<db::DCplxTrans> &trans_mu,
|
||||||
const std::vector<int> &layers,
|
const std::vector<unsigned int> &layers,
|
||||||
const db::DBox ®ion_mu);
|
const db::DBox ®ion_mu);
|
||||||
|
|
||||||
const std::set<lay::ObjectInstPath> *mp_excludes;
|
const std::set<lay::ObjectInstPath> *mp_excludes;
|
||||||
|
|
|
||||||
|
|
@ -337,6 +337,16 @@ NetTracerData::requires_booleans (unsigned int from_layer) const
|
||||||
return r->second;
|
return r->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<unsigned int>
|
||||||
|
NetTracerData::original_layers () const
|
||||||
|
{
|
||||||
|
std::set<unsigned int> ol;
|
||||||
|
for (std::map <unsigned int, std::set <unsigned int> >::const_iterator g = m_original_layers.begin (); g != m_original_layers.end (); ++g) {
|
||||||
|
ol.insert (g->second.begin (), g->second.end ());
|
||||||
|
}
|
||||||
|
return ol;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NetTracerData::clean_l2n_regions ()
|
NetTracerData::clean_l2n_regions ()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -626,6 +626,13 @@ public:
|
||||||
*/
|
*/
|
||||||
void configure_l2n (db::LayoutToNetlist &l2n);
|
void configure_l2n (db::LayoutToNetlist &l2n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the original layers
|
||||||
|
*
|
||||||
|
* These are the layer indexes used for computing the net tracer functions
|
||||||
|
*/
|
||||||
|
std::set<unsigned int> original_layers () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int m_next_log_layer;
|
unsigned int m_next_log_layer;
|
||||||
std::vector <NetTracerConnection> m_connections;
|
std::vector <NetTracerConnection> m_connections;
|
||||||
|
|
|
||||||
|
|
@ -414,9 +414,24 @@ NetTracerDialog::get_net_tracer_setup (const lay::CellView &cv, db::NetTracerDat
|
||||||
db::NetTracerNet *
|
db::NetTracerNet *
|
||||||
NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &stop_search_box, bool trace_path)
|
NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &stop_search_box, bool trace_path)
|
||||||
{
|
{
|
||||||
|
// determine the cellview
|
||||||
|
lay::CellView cv = view ()->cellview (m_cv_index);
|
||||||
|
if (! cv.is_valid ()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up the net tracer environment
|
||||||
|
db::NetTracerData tracer_data;
|
||||||
|
if (! get_net_tracer_setup (cv, tracer_data)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<unsigned int> original_layers = tracer_data.original_layers ();
|
||||||
|
|
||||||
unsigned int start_layer = 0;
|
unsigned int start_layer = 0;
|
||||||
db::Point start_point;
|
db::Point start_point;
|
||||||
db::Shape start_shape;
|
db::Shape start_shape;
|
||||||
|
db::ICplxTrans start_trans;
|
||||||
|
|
||||||
// locate the seed
|
// locate the seed
|
||||||
{
|
{
|
||||||
|
|
@ -426,7 +441,7 @@ NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &sto
|
||||||
|
|
||||||
// go through all visible layers of all cellviews and find a seed shape
|
// go through all visible layers of all cellviews and find a seed shape
|
||||||
for (lay::LayerPropertiesConstIterator lprop = view ()->begin_layers (); ! lprop.at_end (); ++lprop) {
|
for (lay::LayerPropertiesConstIterator lprop = view ()->begin_layers (); ! lprop.at_end (); ++lprop) {
|
||||||
if (lprop->is_visual ()) {
|
if (lprop->is_visual () && lprop->cellview_index () == m_cv_index && original_layers.find ((unsigned int) lprop->layer_index ()) != original_layers.end ()) {
|
||||||
finder.find (view (), *lprop, start_search_box);
|
finder.find (view (), *lprop, start_search_box);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -440,15 +455,10 @@ NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &sto
|
||||||
m_cv_index = r->cv_index ();
|
m_cv_index = r->cv_index ();
|
||||||
start_shape = r->shape ();
|
start_shape = r->shape ();
|
||||||
start_layer = r->layer ();
|
start_layer = r->layer ();
|
||||||
|
start_trans = r->trans ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// determine the cellview
|
|
||||||
lay::CellView cv = view ()->cellview (m_cv_index);
|
|
||||||
if (! cv.is_valid ()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// determine the start point
|
// determine the start point
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -463,20 +473,15 @@ NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &sto
|
||||||
|
|
||||||
// stop if the center start point is not inside the start polygon
|
// stop if the center start point is not inside the start polygon
|
||||||
db::Polygon poly;
|
db::Polygon poly;
|
||||||
if (start_shape.polygon (poly) && db::inside_poly (poly.begin_edge (), start_point) < 0) {
|
if (start_shape.polygon (poly) && db::inside_poly (poly.begin_edge (), start_trans.inverted () * start_point) < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up the net tracer environment
|
|
||||||
db::NetTracerData tracer_data;
|
|
||||||
if (! get_net_tracer_setup (cv, tracer_data)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int stop_layer = 0;
|
unsigned int stop_layer = 0;
|
||||||
db::Point stop_point;
|
db::Point stop_point;
|
||||||
|
db::ICplxTrans stop_trans;
|
||||||
|
|
||||||
// locate the stop shape (the second mouse click)
|
// locate the stop shape (the second mouse click)
|
||||||
if (trace_path) {
|
if (trace_path) {
|
||||||
|
|
@ -486,7 +491,7 @@ NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &sto
|
||||||
|
|
||||||
// go through all visible layers of all cellviews and find a seed shape
|
// go through all visible layers of all cellviews and find a seed shape
|
||||||
for (lay::LayerPropertiesConstIterator lprop = view ()->begin_layers (); ! lprop.at_end (); ++lprop) {
|
for (lay::LayerPropertiesConstIterator lprop = view ()->begin_layers (); ! lprop.at_end (); ++lprop) {
|
||||||
if (lprop->is_visual ()) {
|
if (lprop->is_visual () && lprop->cellview_index () == m_cv_index && original_layers.find ((unsigned int) lprop->layer_index ()) != original_layers.end ()) {
|
||||||
finder.find (view (), *lprop, stop_search_box);
|
finder.find (view (), *lprop, stop_search_box);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -510,10 +515,11 @@ NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &sto
|
||||||
|
|
||||||
stop_point = tt.inverted ().trans (stop_search_box.center ());
|
stop_point = tt.inverted ().trans (stop_search_box.center ());
|
||||||
stop_layer = r->layer ();
|
stop_layer = r->layer ();
|
||||||
|
stop_trans = r->trans ();
|
||||||
|
|
||||||
// stop if the center stop point is not inside the stop polygon
|
// stop if the center stop point is not inside the stop polygon
|
||||||
db::Polygon poly;
|
db::Polygon poly;
|
||||||
if (r->shape ().polygon (poly) && db::inside_poly (poly.begin_edge (), stop_point) < 0) {
|
if (r->shape ().polygon (poly) && db::inside_poly (poly.begin_edge (), stop_trans.inverted () * stop_point) < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue