mirror of https://github.com/KLayout/klayout.git
Netlist browser: fixed a segfault on 'unload all'
This commit is contained in:
parent
0983ebc854
commit
e661bac0a7
|
|
@ -514,6 +514,18 @@ void DeepShapeStore::make_layout (unsigned int layout_index, const db::Recursive
|
|||
m_layout_map[std::make_pair (si, trans)] = layout_index;
|
||||
}
|
||||
|
||||
static unsigned int init_layer (db::Layout &layout, const db::RecursiveShapeIterator &si)
|
||||
{
|
||||
unsigned int layer_index = layout.insert_layer ();
|
||||
|
||||
if (si.layout () && si.layer () < si.layout ()->layers ()) {
|
||||
// try to preserve the layer properties
|
||||
layout.set_properties (layer_index, si.layout ()->get_properties (si.layer ()));
|
||||
}
|
||||
|
||||
return layer_index;
|
||||
}
|
||||
|
||||
DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator &si, double max_area_ratio, size_t max_vertex_count, const db::ICplxTrans &trans)
|
||||
{
|
||||
if (max_area_ratio == 0.0) {
|
||||
|
|
@ -528,7 +540,7 @@ DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator
|
|||
db::Layout &layout = m_layouts[layout_index]->layout;
|
||||
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;
|
||||
|
||||
unsigned int layer_index = layout.insert_layer ();
|
||||
unsigned int layer_index = init_layer (layout, si);
|
||||
builder.set_target_layer (layer_index);
|
||||
|
||||
// The chain of operators for producing clipped and reduced polygon references
|
||||
|
|
@ -571,7 +583,7 @@ DeepLayer DeepShapeStore::create_custom_layer (const db::RecursiveShapeIterator
|
|||
db::Layout &layout = m_layouts[layout_index]->layout;
|
||||
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;
|
||||
|
||||
unsigned int layer_index = layout.insert_layer ();
|
||||
unsigned int layer_index = init_layer (layout, si);
|
||||
builder.set_target_layer (layer_index);
|
||||
|
||||
// Build the working hierarchy from the recursive shape iterator
|
||||
|
|
@ -624,7 +636,7 @@ DeepLayer DeepShapeStore::create_edge_layer (const db::RecursiveShapeIterator &s
|
|||
db::Layout &layout = m_layouts[layout_index]->layout;
|
||||
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;
|
||||
|
||||
unsigned int layer_index = layout.insert_layer ();
|
||||
unsigned int layer_index = init_layer (layout, si);
|
||||
builder.set_target_layer (layer_index);
|
||||
|
||||
// The chain of operators for producing edges
|
||||
|
|
@ -654,7 +666,7 @@ DeepLayer DeepShapeStore::create_edge_pair_layer (const db::RecursiveShapeIterat
|
|||
db::Layout &layout = m_layouts[layout_index]->layout;
|
||||
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;
|
||||
|
||||
unsigned int layer_index = layout.insert_layer ();
|
||||
unsigned int layer_index = init_layer (layout, si);
|
||||
builder.set_target_layer (layer_index);
|
||||
|
||||
// The chain of operators for producing the edge pairs
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ namespace db
|
|||
* description(<text>) - an arbitrary description text [short key: B]
|
||||
* unit(<unit>) - specifies the database unit [short key: U]
|
||||
* top(<circuit>) - specifies the name of the top circuit [short key: W]
|
||||
* layer(<name>) - define a layer [short key: L]
|
||||
* layer(<name> <source-spec>?) - define a layer [short key: L]
|
||||
* connect(<layer1> <name> ...) - connects layer1 with the following layers [short key: C]
|
||||
* global(<layer> <net-name> ...)
|
||||
* - connects the shapes of the layer with the given global
|
||||
|
|
|
|||
|
|
@ -201,9 +201,21 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n)
|
|||
} else if (test (skeys::layer_key) || test (lkeys::layer_key)) {
|
||||
|
||||
Brace br (this);
|
||||
std::string layer;
|
||||
std::string layer, lspec;
|
||||
read_word_or_quoted (layer);
|
||||
delete l2n->make_layer (layer);
|
||||
if (br) {
|
||||
read_word_or_quoted (lspec);
|
||||
}
|
||||
|
||||
std::auto_ptr<db::Region> region (l2n->make_layer (layer));
|
||||
if (! lspec.empty ()) {
|
||||
unsigned int layer_index = l2n->layer_of (*region);
|
||||
tl::Extractor ex (lspec.c_str ());
|
||||
db::LayerProperties lp;
|
||||
lp.read (ex);
|
||||
l2n->internal_layout ()->set_properties (layer_index, lp);
|
||||
}
|
||||
|
||||
br.done ();
|
||||
|
||||
} else if (test (skeys::class_key) || test (lkeys::class_key)) {
|
||||
|
|
|
|||
|
|
@ -123,7 +123,12 @@ void std_writer_impl<Keys>::write (const db::LayoutToNetlist *l2n)
|
|||
*mp_stream << endl << "# Mask layers" << endl;
|
||||
}
|
||||
for (db::Connectivity::layer_iterator l = l2n->connectivity ().begin_layers (); l != l2n->connectivity ().end_layers (); ++l) {
|
||||
*mp_stream << Keys::layer_key << "(" << name_for_layer (l2n, *l) << ")" << endl;
|
||||
*mp_stream << Keys::layer_key << "(" << name_for_layer (l2n, *l);
|
||||
db::LayerProperties lp = ly->get_properties (*l);
|
||||
if (! lp.is_null ()) {
|
||||
*mp_stream << " " << tl::to_word_or_quoted_string (lp.to_string ());
|
||||
}
|
||||
*mp_stream << ")" << endl;
|
||||
}
|
||||
|
||||
if (! Keys::is_short ()) {
|
||||
|
|
|
|||
|
|
@ -1754,8 +1754,17 @@ NetlistBrowserPage::set_highlight_style (QColor color, int line_width, int verte
|
|||
void
|
||||
NetlistBrowserPage::set_view (lay::LayoutView *view, unsigned int cv_index)
|
||||
{
|
||||
if (mp_view) {
|
||||
mp_view->layer_list_changed_event.remove (this, &NetlistBrowserPage::layer_list_changed);
|
||||
}
|
||||
|
||||
mp_view = view;
|
||||
m_cv_index = cv_index;
|
||||
|
||||
if (mp_view) {
|
||||
mp_view->layer_list_changed_event.add (this, &NetlistBrowserPage::layer_list_changed);
|
||||
}
|
||||
|
||||
update_highlights ();
|
||||
}
|
||||
|
||||
|
|
@ -1777,6 +1786,12 @@ NetlistBrowserPage::set_max_shape_count (size_t max_shape_count)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
NetlistBrowserPage::layer_list_changed (int)
|
||||
{
|
||||
update_highlights ();
|
||||
}
|
||||
|
||||
void
|
||||
NetlistBrowserPage::anchor_clicked (const QString &a)
|
||||
{
|
||||
|
|
@ -2052,29 +2067,26 @@ NetlistBrowserPage::show_all (bool f)
|
|||
void
|
||||
NetlistBrowserPage::set_l2ndb (db::LayoutToNetlist *database)
|
||||
{
|
||||
if (database != mp_database.get ()) {
|
||||
|
||||
mp_database.reset (database);
|
||||
clear_markers ();
|
||||
highlight_nets (std::vector<const db::Net *> ());
|
||||
|
||||
if (! database) {
|
||||
directory_tree->setModel (0);
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: with the tree as the parent, the tree will take over ownership of the model
|
||||
NetlistBrowserModel *new_model = new NetlistBrowserModel (directory_tree, database, &m_colorizer);
|
||||
|
||||
directory_tree->setModel (new_model);
|
||||
connect (directory_tree->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (current_index_changed (const QModelIndex &)));
|
||||
connect (directory_tree->selectionModel (), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (net_selection_changed ()));
|
||||
|
||||
directory_tree->header ()->setSortIndicatorShown (true);
|
||||
|
||||
find_text->setText (QString ());
|
||||
mp_database.reset (database);
|
||||
clear_markers ();
|
||||
highlight_nets (std::vector<const db::Net *> ());
|
||||
|
||||
if (! database) {
|
||||
delete directory_tree->model ();
|
||||
directory_tree->setModel (0);
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: with the tree as the parent, the tree will take over ownership of the model
|
||||
NetlistBrowserModel *new_model = new NetlistBrowserModel (directory_tree, database, &m_colorizer);
|
||||
|
||||
directory_tree->setModel (new_model);
|
||||
connect (directory_tree->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (current_index_changed (const QModelIndex &)));
|
||||
connect (directory_tree->selectionModel (), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (net_selection_changed ()));
|
||||
|
||||
directory_tree->header ()->setSortIndicatorShown (true);
|
||||
|
||||
find_text->setText (QString ());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -2203,11 +2215,22 @@ NetlistBrowserPage::update_highlights ()
|
|||
return;
|
||||
}
|
||||
|
||||
const db::Layout &original_layout = mp_view->cellview (m_cv_index)->layout ();
|
||||
|
||||
const db::Layout *layout = mp_database->internal_layout ();
|
||||
if (! layout) {
|
||||
return;
|
||||
}
|
||||
|
||||
// a map of display properties vs. layer properties
|
||||
|
||||
std::map<db::LayerProperties, lay::LayerPropertiesConstIterator> display_by_lp;
|
||||
for (lay::LayerPropertiesConstIterator lp = mp_view->begin_layers (); ! lp.at_end (); ++lp) {
|
||||
if (! lp->has_children () && lp->cellview_index () == int (m_cv_index) && lp->layer_index () >= 0 && (unsigned int) lp->layer_index () < original_layout.layers ()) {
|
||||
display_by_lp.insert (std::make_pair (original_layout.get_properties (lp->layer_index ()), lp));
|
||||
}
|
||||
}
|
||||
|
||||
// @@@std::map<unsigned int, std::vector<db::DCplxTrans> > tv_by_layer = mp_view->cv_transform_variants_by_layer (m_cv_index);
|
||||
std::vector<db::DCplxTrans> tv = mp_view->cv_transform_variants (m_cv_index);
|
||||
|
||||
|
|
@ -2228,7 +2251,8 @@ NetlistBrowserPage::update_highlights ()
|
|||
const db::Connectivity &conn = mp_database->connectivity ();
|
||||
for (db::Connectivity::layer_iterator layer = conn.begin_layers (); layer != conn.end_layers (); ++layer) {
|
||||
|
||||
// @@@ TODO: how to get the original layer?
|
||||
db::LayerProperties lp = layout->get_properties (*layer);
|
||||
std::map<db::LayerProperties, lay::LayerPropertiesConstIterator>::const_iterator display = display_by_lp.find (lp);
|
||||
|
||||
db::recursive_cluster_shape_iterator<db::PolygonRef> shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id);
|
||||
while (! shapes.at_end ()) {
|
||||
|
|
@ -2241,25 +2265,32 @@ NetlistBrowserPage::update_highlights ()
|
|||
mp_markers.push_back (new lay::Marker (mp_view, m_cv_index));
|
||||
mp_markers.back ()->set (*shapes, shapes.trans (), tv);
|
||||
|
||||
#if 0
|
||||
// @@@
|
||||
if (! original.at_end ()) {
|
||||
mp_markers.back ()->set_line_width (original->width (true));
|
||||
if (net_color.isValid ()) {
|
||||
|
||||
mp_markers.back ()->set_color (net_color);
|
||||
mp_markers.back ()->set_frame_color (net_color);
|
||||
|
||||
} else if (display != display_by_lp.end ()) {
|
||||
|
||||
mp_markers.back ()->set_line_width (display->second->width (true));
|
||||
mp_markers.back ()->set_vertex_size (1);
|
||||
mp_markers.back ()->set_dither_pattern (original->dither_pattern (true));
|
||||
if (view ()->background_color ().green () < 128) {
|
||||
mp_markers.back ()->set_color (original->eff_fill_color_brighter (true, (m_marker_intensity * 255) / 100));
|
||||
mp_markers.back ()->set_frame_color (original->eff_frame_color_brighter (true, (m_marker_intensity * 255) / 100));
|
||||
mp_markers.back ()->set_dither_pattern (display->second->dither_pattern (true));
|
||||
if (mp_view->background_color ().green () < 128) {
|
||||
mp_markers.back ()->set_color (display->second->eff_fill_color_brighter (true, (m_marker_intensity * 255) / 100));
|
||||
mp_markers.back ()->set_frame_color (display->second->eff_frame_color_brighter (true, (m_marker_intensity * 255) / 100));
|
||||
} else {
|
||||
mp_markers.back ()->set_color (original->eff_fill_color_brighter (true, (-m_marker_intensity * 255) / 100));
|
||||
mp_markers.back ()->set_frame_color (original->eff_frame_color_brighter (true, (-m_marker_intensity * 255) / 100));
|
||||
mp_markers.back ()->set_color (display->second->eff_fill_color_brighter (true, (-m_marker_intensity * 255) / 100));
|
||||
mp_markers.back ()->set_frame_color (display->second->eff_frame_color_brighter (true, (-m_marker_intensity * 255) / 100));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// fallback color
|
||||
QColor net_color = mp_view->background_color ().green () < 128 ? QColor (Qt::white) : QColor (Qt::black);
|
||||
mp_markers.back ()->set_color (net_color);
|
||||
mp_markers.back ()->set_frame_color (net_color);
|
||||
|
||||
}
|
||||
#endif
|
||||
// @@@
|
||||
mp_markers.back ()->set_color (net_color);
|
||||
mp_markers.back ()->set_frame_color (net_color);
|
||||
// @@@
|
||||
|
||||
if (m_marker_line_width >= 0) {
|
||||
mp_markers.back ()->set_line_width (m_marker_line_width);
|
||||
|
|
|
|||
|
|
@ -214,7 +214,8 @@ private:
|
|||
*/
|
||||
class NetlistBrowserPage
|
||||
: public QFrame,
|
||||
public Ui::NetlistBrowserPage
|
||||
public Ui::NetlistBrowserPage,
|
||||
public tl::Object
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
|
@ -340,6 +341,7 @@ private:
|
|||
void highlight_nets (const std::vector<const db::Net *> &nets);
|
||||
std::vector<const db::Net *> selected_nets ();
|
||||
void set_color_for_selected_nets (const QColor &color);
|
||||
void layer_list_changed (int);
|
||||
};
|
||||
|
||||
} // namespace lay
|
||||
|
|
|
|||
|
|
@ -9,15 +9,15 @@ unit(0.001)
|
|||
# This section lists the mask layers (drawing or derived) and their connections.
|
||||
|
||||
# Mask layers
|
||||
layer(poly)
|
||||
layer(poly_lbl)
|
||||
layer(diff_cont)
|
||||
layer(poly_cont)
|
||||
layer(metal1)
|
||||
layer(metal1_lbl)
|
||||
layer(via1)
|
||||
layer(metal2)
|
||||
layer(metal2_lbl)
|
||||
layer(poly '3/0')
|
||||
layer(poly_lbl '3/1')
|
||||
layer(diff_cont '4/0')
|
||||
layer(poly_cont '5/0')
|
||||
layer(metal1 '6/0')
|
||||
layer(metal1_lbl '6/1')
|
||||
layer(via1 '7/0')
|
||||
layer(metal2 '8/0')
|
||||
layer(metal2_lbl '8/1')
|
||||
layer(psd)
|
||||
layer(nsd)
|
||||
|
||||
|
|
|
|||
|
|
@ -10,16 +10,16 @@ unit(0.001)
|
|||
|
||||
# Mask layers
|
||||
layer(rbulk)
|
||||
layer(nwell)
|
||||
layer(poly)
|
||||
layer(poly_lbl)
|
||||
layer(diff_cont)
|
||||
layer(poly_cont)
|
||||
layer(metal1)
|
||||
layer(metal1_lbl)
|
||||
layer(via1)
|
||||
layer(metal2)
|
||||
layer(metal2_lbl)
|
||||
layer(nwell '1/0')
|
||||
layer(poly '3/0')
|
||||
layer(poly_lbl '3/1')
|
||||
layer(diff_cont '4/0')
|
||||
layer(poly_cont '5/0')
|
||||
layer(metal1 '6/0')
|
||||
layer(metal1_lbl '6/1')
|
||||
layer(via1 '7/0')
|
||||
layer(metal2 '8/0')
|
||||
layer(metal2_lbl '8/1')
|
||||
layer(ntie)
|
||||
layer(psd)
|
||||
layer(ptie)
|
||||
|
|
|
|||
|
|
@ -2,16 +2,16 @@
|
|||
W(RINGO)
|
||||
U(0.001)
|
||||
L(rbulk)
|
||||
L(nwell)
|
||||
L(poly)
|
||||
L(poly_lbl)
|
||||
L(diff_cont)
|
||||
L(poly_cont)
|
||||
L(metal1)
|
||||
L(metal1_lbl)
|
||||
L(via1)
|
||||
L(metal2)
|
||||
L(metal2_lbl)
|
||||
L(nwell '1/0')
|
||||
L(poly '3/0')
|
||||
L(poly_lbl '3/1')
|
||||
L(diff_cont '4/0')
|
||||
L(poly_cont '5/0')
|
||||
L(metal1 '6/0')
|
||||
L(metal1_lbl '6/1')
|
||||
L(via1 '7/0')
|
||||
L(metal2 '8/0')
|
||||
L(metal2_lbl '8/1')
|
||||
L(ntie)
|
||||
L(psd)
|
||||
L(ptie)
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
#%l2n-klayout
|
||||
W(RINGO)
|
||||
U(0.001)
|
||||
L(poly)
|
||||
L(poly_lbl)
|
||||
L(diff_cont)
|
||||
L(poly_cont)
|
||||
L(metal1)
|
||||
L(metal1_lbl)
|
||||
L(via1)
|
||||
L(metal2)
|
||||
L(metal2_lbl)
|
||||
L(poly '3/0')
|
||||
L(poly_lbl '3/1')
|
||||
L(diff_cont '4/0')
|
||||
L(poly_cont '5/0')
|
||||
L(metal1 '6/0')
|
||||
L(metal1_lbl '6/1')
|
||||
L(via1 '7/0')
|
||||
L(metal2 '8/0')
|
||||
L(metal2_lbl '8/1')
|
||||
L(psd)
|
||||
L(nsd)
|
||||
C(poly poly poly_lbl poly_cont)
|
||||
|
|
|
|||
Loading…
Reference in New Issue