From 8a0a6cad04ea80e77f0504c5cc672283051f217d Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 24 Mar 2024 11:29:18 +0100 Subject: [PATCH] Refactoring solution such that loading a layout file into a marker database also works from command line (-m) and scripts --- src/layui/layui/rdbMarkerBrowserDialog.cc | 159 +------------------- src/layui/layui/rdbMarkerBrowserDialog.h | 2 - src/rdb/rdb/rdb.cc | 170 +++++++++++++++++++++- src/rdb/rdb/rdb.h | 11 ++ 4 files changed, 179 insertions(+), 163 deletions(-) diff --git a/src/layui/layui/rdbMarkerBrowserDialog.cc b/src/layui/layui/rdbMarkerBrowserDialog.cc index 7502734ad..800025a13 100644 --- a/src/layui/layui/rdbMarkerBrowserDialog.cc +++ b/src/layui/layui/rdbMarkerBrowserDialog.cc @@ -413,26 +413,6 @@ BEGIN_PROTECTED END_PROTECTED } -void -MarkerBrowserDialog::read_db_from_layout (rdb::Database *db, const std::string &filename) -{ - // try reading a layout file - db::Layout layout; - tl::InputStream is (m_open_filename); - db::Reader reader (is); - - reader.read (layout); - - std::vector > layers; - for (auto l = layout.begin_layers (); l != layout.end_layers (); ++l) { - layers.push_back (std::make_pair ((*l).first, std::string ())); - } - - if (layout.begin_top_down () != layout.end_top_down ()) { - scan_layout (db, layout, *layout.begin_top_down (), layers, false /*hierarchical*/); - } -} - void MarkerBrowserDialog::open_clicked () { @@ -455,20 +435,7 @@ BEGIN_PROTECTED if (open_dialog.get_open (m_open_filename)) { std::unique_ptr db (new rdb::Database ()); - - bool ok = false; - try { - // try reading a stream file - read_db_from_layout (db.get (), m_open_filename); - ok = true; - } catch (tl::Exception &ex) { - // continue - } - - if (! ok) { - // try reading database directly. - db->load (m_open_filename); - } + db->load (m_open_filename); int rdb_index = view ()->add_rdb (db.release ()); mp_ui->rdb_cb->setCurrentIndex (rdb_index); @@ -817,134 +784,12 @@ MarkerBrowserDialog::scan_layer_flat_or_hierarchical (bool flat) std::unique_ptr rdb (new rdb::Database ()); - scan_layout (rdb.get (), layout, cv.cell_index (), layer_indexes, flat); + rdb->scan_layout (layout, cv.cell_index (), layer_indexes, flat); unsigned int rdb_index = view ()->add_rdb (rdb.release ()); view ()->open_rdb_browser (rdb_index, cv_index); } -void -MarkerBrowserDialog::scan_layout (rdb::Database *rdb, const db::Layout &layout, db::cell_index_type cell_index, const std::vector > &layers_and_descriptions, bool flat) -{ - tl::AbsoluteProgress progress (tl::to_string (QObject::tr ("Shapes To Markers")), 10000); - progress.set_format (tl::to_string (QObject::tr ("%.0f0000 markers"))); - progress.set_unit (10000); - - rdb->set_name ("Shapes"); - rdb->set_top_cell_name (layout.cell_name (cell_index)); - rdb::Cell *rdb_top_cell = rdb->create_cell (rdb->top_cell_name ()); - - std::string desc; - - if (layers_and_descriptions.size () == 1) { - - if (flat) { - desc = tl::to_string (tr ("Flat shapes of layer ")); - } else { - desc = tl::to_string (tr ("Hierarchical shapes of layer ")); - } - - desc += layout.get_properties (layers_and_descriptions.front ().first).to_string (); - - } else if (layers_and_descriptions.size () < 4 && layers_and_descriptions.size () > 0) { - - if (flat) { - desc = tl::to_string (tr ("Flat shapes of layers ")); - } else { - desc = tl::to_string (tr ("Hierarchical shapes of layers ")); - } - - for (auto l = layers_and_descriptions.begin (); l != layers_and_descriptions.end (); ++l) { - if (l != layers_and_descriptions.begin ()) { - desc += ","; - } - desc += layout.get_properties (l->first).to_string (); - } - - } else { - - if (flat) { - desc = tl::sprintf (tl::to_string (tr ("Flat shapes of %d layers")), int (layers_and_descriptions.size ())); - } else { - desc = tl::sprintf (tl::to_string (tr ("Hierarchical shapes of %d layers")), int (layers_and_descriptions.size ())); - } - - } - - desc += " "; - desc += tl::to_string (tr ("from cell ")); - desc += layout.cell_name (cell_index); - rdb->set_description (desc); - - if (flat) { - - for (auto l = layers_and_descriptions.begin (); l != layers_and_descriptions.end (); ++l) { - - rdb::Category *cat = rdb->create_category (l->second.empty () ? layout.get_properties (l->first).to_string () : l->second); - - db::RecursiveShapeIterator shape (layout, layout.cell (cell_index), l->first); - while (! shape.at_end ()) { - - rdb::create_item_from_shape (rdb, rdb_top_cell->id (), cat->id (), db::CplxTrans (layout.dbu ()) * shape.trans (), *shape); - - ++progress; - ++shape; - - } - - } - - } else { - - std::set called_cells; - called_cells.insert (cell_index); - layout.cell (cell_index).collect_called_cells (called_cells); - - for (auto l = layers_and_descriptions.begin (); l != layers_and_descriptions.end (); ++l) { - - rdb::Category *cat = rdb->create_category (l->second.empty () ? layout.get_properties (l->first).to_string () : l->second); - - for (db::Layout::const_iterator cid = layout.begin (); cid != layout.end (); ++cid) { - - if (called_cells.find (cid->cell_index ()) == called_cells.end ()) { - continue; - } - - const db::Cell &cell = *cid; - if (! cell.shapes (l->first).empty ()) { - - std::string cn = layout.cell_name (cell.cell_index ()); - const rdb::Cell *rdb_cell = rdb->cell_by_qname (cn); - if (! rdb_cell) { - - rdb::Cell *rdb_cell_nc = rdb->create_cell (cn); - rdb_cell = rdb_cell_nc; - - std::pair ctx = db::find_layout_context (layout, cell.cell_index (), cell_index); - if (ctx.first) { - db::DCplxTrans t = db::DCplxTrans (layout.dbu ()) * db::DCplxTrans (ctx.second) * db::DCplxTrans (1.0 / layout.dbu ()); - rdb_cell_nc->references ().insert (Reference (t, rdb_top_cell->id ())); - } - - } - - for (db::ShapeIterator shape = cell.shapes (l->first).begin (db::ShapeIterator::All); ! shape.at_end (); ++shape) { - - rdb::create_item_from_shape (rdb, rdb_cell->id (), cat->id (), db::CplxTrans (layout.dbu ()), *shape); - - ++progress; - - } - - } - - } - - } - - } -} - void MarkerBrowserDialog::menu_activated (const std::string &symbol) { diff --git a/src/layui/layui/rdbMarkerBrowserDialog.h b/src/layui/layui/rdbMarkerBrowserDialog.h index 3b50f1fa7..482913f6a 100644 --- a/src/layui/layui/rdbMarkerBrowserDialog.h +++ b/src/layui/layui/rdbMarkerBrowserDialog.h @@ -109,8 +109,6 @@ private: void scan_layer (); void scan_layer_flat (); void scan_layer_flat_or_hierarchical (bool flat); - void scan_layout (rdb::Database *db, const db::Layout &layout, db::cell_index_type cell_index, const std::vector > &layers_and_descriptions, bool flat); - void read_db_from_layout (rdb::Database *db, const std::string &filename); }; } diff --git a/src/rdb/rdb/rdb.cc b/src/rdb/rdb/rdb.cc index 887383198..e219dfc52 100644 --- a/src/rdb/rdb/rdb.cc +++ b/src/rdb/rdb/rdb.cc @@ -23,11 +23,13 @@ #include "rdb.h" #include "rdbReader.h" +#include "rdbUtils.h" #include "tlString.h" #include "tlAssert.h" #include "tlStream.h" #include "tlLog.h" #include "tlBase64.h" +#include "tlProgress.h" #include "dbPolygon.h" #include "dbBox.h" #include "dbEdge.h" @@ -35,6 +37,10 @@ #include "dbPath.h" #include "dbText.h" #include "dbShape.h" +#include "dbLayout.h" +#include "dbLayoutUtils.h" +#include "dbReader.h" +#include "dbRecursiveShapeIterator.h" #if defined(HAVE_QT) # include @@ -1566,16 +1572,49 @@ Database::clear () mp_categories->set_database (this); } +static void +read_db_from_layout (rdb::Database *db, tl::InputStream &is) +{ + // try reading a layout file + db::Layout layout; + db::Reader reader (is); + + reader.read (layout); + + std::vector > layers; + for (auto l = layout.begin_layers (); l != layout.end_layers (); ++l) { + layers.push_back (std::make_pair ((*l).first, std::string ())); + } + + if (layout.begin_top_down () != layout.end_top_down ()) { + db->scan_layout (layout, *layout.begin_top_down (), layers, false /*hierarchical*/); + } +} + void Database::load (const std::string &fn) { tl::log << "Loading RDB from " << fn; - tl::InputStream stream (fn); - rdb::Reader reader (stream); - clear (); - reader.read (*this); + + tl::InputStream stream (fn); + + bool ok = false; + try { + // try reading a stream file + read_db_from_layout (this, stream); + ok = true; + } catch (tl::Exception &) { + stream.reset (); + } + + if (! ok) { + // try reading a DB file + clear (); + rdb::Reader reader (stream); + reader.read (*this); + } set_filename (stream.absolute_path ()); set_name (stream.filename ()); @@ -1587,5 +1626,128 @@ Database::load (const std::string &fn) } } +void +Database::scan_layout (const db::Layout &layout, db::cell_index_type cell_index, const std::vector > &layers_and_descriptions, bool flat) +{ + tl::AbsoluteProgress progress (tl::to_string (QObject::tr ("Shapes To Markers")), 10000); + progress.set_format (tl::to_string (QObject::tr ("%.0f0000 markers"))); + progress.set_unit (10000); + + set_name ("Shapes"); + set_top_cell_name (layout.cell_name (cell_index)); + rdb::Cell *rdb_top_cell = create_cell (top_cell_name ()); + + std::string desc; + + if (layers_and_descriptions.size () == 1) { + + if (flat) { + desc = tl::to_string (tr ("Flat shapes of layer ")); + } else { + desc = tl::to_string (tr ("Hierarchical shapes of layer ")); + } + + desc += layout.get_properties (layers_and_descriptions.front ().first).to_string (); + + } else if (layers_and_descriptions.size () < 4 && layers_and_descriptions.size () > 0) { + + if (flat) { + desc = tl::to_string (tr ("Flat shapes of layers ")); + } else { + desc = tl::to_string (tr ("Hierarchical shapes of layers ")); + } + + for (auto l = layers_and_descriptions.begin (); l != layers_and_descriptions.end (); ++l) { + if (l != layers_and_descriptions.begin ()) { + desc += ","; + } + desc += layout.get_properties (l->first).to_string (); + } + + } else { + + if (flat) { + desc = tl::sprintf (tl::to_string (tr ("Flat shapes of %d layers")), int (layers_and_descriptions.size ())); + } else { + desc = tl::sprintf (tl::to_string (tr ("Hierarchical shapes of %d layers")), int (layers_and_descriptions.size ())); + } + + } + + desc += " "; + desc += tl::to_string (tr ("from cell ")); + desc += layout.cell_name (cell_index); + set_description (desc); + + if (flat) { + + for (auto l = layers_and_descriptions.begin (); l != layers_and_descriptions.end (); ++l) { + + rdb::Category *cat = create_category (l->second.empty () ? layout.get_properties (l->first).to_string () : l->second); + + db::RecursiveShapeIterator shape (layout, layout.cell (cell_index), l->first); + while (! shape.at_end ()) { + + rdb::create_item_from_shape (this, rdb_top_cell->id (), cat->id (), db::CplxTrans (layout.dbu ()) * shape.trans (), *shape); + + ++progress; + ++shape; + + } + + } + + } else { + + std::set called_cells; + called_cells.insert (cell_index); + layout.cell (cell_index).collect_called_cells (called_cells); + + for (auto l = layers_and_descriptions.begin (); l != layers_and_descriptions.end (); ++l) { + + rdb::Category *cat = create_category (l->second.empty () ? layout.get_properties (l->first).to_string () : l->second); + + for (db::Layout::const_iterator cid = layout.begin (); cid != layout.end (); ++cid) { + + if (called_cells.find (cid->cell_index ()) == called_cells.end ()) { + continue; + } + + const db::Cell &cell = *cid; + if (! cell.shapes (l->first).empty ()) { + + std::string cn = layout.cell_name (cell.cell_index ()); + const rdb::Cell *rdb_cell = cell_by_qname (cn); + if (! rdb_cell) { + + rdb::Cell *rdb_cell_nc = create_cell (cn); + rdb_cell = rdb_cell_nc; + + std::pair ctx = db::find_layout_context (layout, cell.cell_index (), cell_index); + if (ctx.first) { + db::DCplxTrans t = db::DCplxTrans (layout.dbu ()) * db::DCplxTrans (ctx.second) * db::DCplxTrans (1.0 / layout.dbu ()); + rdb_cell_nc->references ().insert (Reference (t, rdb_top_cell->id ())); + } + + } + + for (db::ShapeIterator shape = cell.shapes (l->first).begin (db::ShapeIterator::All); ! shape.at_end (); ++shape) { + + rdb::create_item_from_shape (this, rdb_cell->id (), cat->id (), db::CplxTrans (layout.dbu ()), *shape); + + ++progress; + + } + + } + + } + + } + + } +} + + } // namespace rdb diff --git a/src/rdb/rdb/rdb.h b/src/rdb/rdb/rdb.h index a7859f60e..22970cd3c 100644 --- a/src/rdb/rdb/rdb.h +++ b/src/rdb/rdb/rdb.h @@ -50,6 +50,7 @@ namespace tl namespace db { class Shape; + class Layout; } namespace rdb @@ -2317,6 +2318,16 @@ public: */ void load (const std::string &filename); + /** + * @brief Scans a layout into this RDB + * + * @param layout The layout to scan + * @param cell_index The top cell to scan + * @param layers_and_descriptions The layers and (optional) descriptions/names of the layer to scan + * @param flat True, to perform a flat scan + */ + void scan_layout (const db::Layout &layout, db::cell_index_type cell_index, const std::vector > &layers_and_descriptions, bool flat); + private: std::string m_generator; std::string m_filename;