WIP: some refactoring, vias switch layers now.

This commit is contained in:
Matthias Koefferlein 2025-08-17 21:50:02 +02:00
parent 0da4f694ca
commit d8e271339e
9 changed files with 221 additions and 118 deletions

View File

@ -21,6 +21,8 @@
*/
#include "dbVia.h"
#include "dbLibraryManager.h"
#include "dbPCellDeclaration.h"
namespace db
{
@ -40,4 +42,37 @@ ViaType::init ()
top_wired = true;
}
// ---------------------------------------------------------------------------------------
std::vector<SelectedViaDefinition>
find_via_definitions_for (const std::string &technology, const db::LayerProperties &layer)
{
std::vector<SelectedViaDefinition> via_defs;
// Find vias with corresponding top an bottom layers
for (auto l = db::LibraryManager::instance ().begin (); l != db::LibraryManager::instance ().end (); ++l) {
db::Library *lib = db::LibraryManager::instance ().lib (l->second);
if (lib->for_technologies () && ! lib->is_for_technology (technology)) {
continue;
}
for (auto pc = lib->layout ().begin_pcells (); pc != lib->layout ().end_pcells (); ++pc) {
const db::PCellDeclaration *pcell = lib->layout ().pcell_declaration (pc->second);
auto via_types = pcell->via_types ();
for (auto vt = via_types.begin (); vt != via_types.end (); ++vt) {
if ((vt->bottom.log_equal (layer) && vt->bottom_wired) || (vt->top.log_equal (layer) && vt->top_wired)) {
via_defs.push_back (SelectedViaDefinition (lib, pc->second, *vt));
}
}
}
}
return via_defs;
}
}

View File

@ -26,6 +26,7 @@
#include "dbCommon.h"
#include "dbLayerProperties.h"
#include "dbLibrary.h"
#include <string>
@ -158,6 +159,38 @@ private:
void init ();
};
/**
* @brief Provides a via definition that is selected by "find_via_definitions_for"
*/
struct SelectedViaDefinition
{
SelectedViaDefinition ()
: lib (0), pcell (0)
{ }
SelectedViaDefinition (db::Library *_lib, db::pcell_id_type _pcell, const db::ViaType &_via_type)
: lib (_lib), pcell (_pcell), via_type (_via_type)
{ }
/**
* @brief The library from which the via is taken
*/
db::Library *lib;
/**
* @brief The PCell from which the via is taken
*/
db::pcell_id_type pcell;
/**
* @brief The selected via type
*/
db::ViaType via_type;
};
DB_PUBLIC std::vector<SelectedViaDefinition>
find_via_definitions_for (const std::string &technology, const db::LayerProperties &layer);
}
#endif

View File

@ -43,6 +43,7 @@
#if defined(HAVE_QT)
# include <QApplication>
# include <QLayout>
# include <QMessageBox>
#endif
namespace edt
@ -506,40 +507,6 @@ private:
static tl::RegisteredClass<lay::PluginDeclaration> config_decl_main (new edt::MainPluginDeclaration (tl::to_string (tr ("Instances and shapes"))), 4000, "edt::MainService");
void
commit_recent (lay::LayoutViewBase *view)
{
#if defined(HAVE_QT)
lay::EditorOptionsPages *eo_pages = view->editor_options_pages ();
if (!eo_pages) {
return;
}
for (std::vector<lay::EditorOptionsPage *>::const_iterator op = eo_pages->pages ().begin (); op != eo_pages->pages ().end (); ++op) {
if ((*op)->active ()) {
(*op)->commit_recent (view);
}
}
#endif
}
void
config_recent_for_layer (lay::LayoutViewBase *view, const db::LayerProperties &lp, int cv_index)
{
#if defined(HAVE_QT)
lay::EditorOptionsPages *eo_pages = view->editor_options_pages ();
if (!eo_pages) {
return;
}
for (std::vector<lay::EditorOptionsPage *>::const_iterator op = eo_pages->pages ().begin (); op != eo_pages->pages ().end (); ++op) {
if ((*op)->active ()) {
(*op)->config_recent_for_layer (view, lp, cv_index);
}
}
#endif
}
class PartialPluginDeclaration
: public PluginDeclarationBase
{

View File

@ -24,6 +24,7 @@
#ifndef HDR_edtPlugin
#define HDR_edtPlugin
#include "edtCommon.h"
#include "layPlugin.h"
#include <vector>
@ -57,16 +58,6 @@ namespace edt
bool points_enabled ();
bool texts_enabled ();
bool instances_enabled ();
/**
* @brief Commits the current configuration for the recently used configuration list
*/
void commit_recent (lay::LayoutViewBase *view);
/**
* @brief Configure attributes for the most-recent entry with the given layer
*/
void config_recent_for_layer (lay::LayoutViewBase *view, const db::LayerProperties &lp, int cv_index);
}
#endif

View File

@ -365,40 +365,6 @@ RecentConfigurationPage::update_list (const std::list<std::vector<std::string> >
mp_tree_widget->header ()->resizeSections (QHeaderView::ResizeToContents);
}
static bool
set_or_request_current_layer (QWidget *parent, lay::LayoutViewBase *view, unsigned int cv_index, const db::LayerProperties &lp)
{
bool ok = view->set_current_layer (cv_index, lp);
if (ok) {
return true;
}
if (! view->control_panel ()) {
return false;
}
const lay::CellView &cv = view->cellview (cv_index);
if (! cv.is_valid ()) {
return false;
}
if (QMessageBox::question (parent, tr ("Create Layer"), tr ("Layer %1 does not exist yet. Create it now?").arg (tl::to_qstring (lp.to_string ()))) == QMessageBox::Yes) {
lay::LayerPropertiesNode lpn;
lpn.set_source (lay::ParsedLayerSource (lp, cv_index));
view->init_layer_properties (lpn);
view->transaction (tl::to_string (QObject::tr ("Create new layer")));
view->set_current_layer (lay::LayerPropertiesConstIterator (& view->insert_layer (view->end_layers (), lpn)));
view->commit ();
return true;
}
return false;
}
void
RecentConfigurationPage::item_clicked (QTreeWidgetItem *item)
{
@ -418,7 +384,7 @@ RecentConfigurationPage::item_clicked (QTreeWidgetItem *item)
ex.read (cv_index);
}
set_or_request_current_layer (item->treeWidget (), view (), cv_index, lp);
edt::set_or_request_current_layer (view (), lp, cv_index);
} else {
dispatcher ()->config_set (c->cfg_name, v);

View File

@ -30,11 +30,10 @@
#include "edtService.h"
#include "edtPlugin.h"
#include "dbEdge.h"
#include "dbLibrary.h"
#include "dbLibraryManager.h"
#include "dbPCellDeclaration.h"
#include "dbVia.h"
#include "dbPolygonTools.h"
#include "dbEdgeProcessor.h"
#include "dbLibraryManager.h"
#include "layMarker.h"
#include "layLayerProperties.h"
#include "layLayoutViewBase.h"
@ -155,6 +154,26 @@ ShapeEditService::get_edit_layer ()
edt::config_recent_for_layer (view (), cv->layout ().get_properties ((unsigned int) layer), cv_index);
}
void
ShapeEditService::change_edit_layer (const db::LayerProperties &lp)
{
if (! mp_layout) {
return;
}
int layer = mp_layout->get_layer_maybe (lp);
if (layer < 0) {
layer = mp_layout->insert_layer (lp);
}
m_layer = (unsigned int) layer;
edt::set_or_request_current_layer (view (), lp, m_cv_index);
// fetches the last configuration for the given layer
view ()->set_active_cellview_index (m_cv_index);
edt::config_recent_for_layer (view (), lp, m_cv_index);
}
void
ShapeEditService::update_edit_layer (const lay::LayerPropertiesConstIterator &cl)
{
@ -1471,41 +1490,9 @@ PathService::via ()
*/
db::LayerProperties lp = layout ().get_properties (layer ());
std::vector<db::SelectedViaDefinition> via_defs = db::find_via_definitions_for (layout ().technology_name (), lp);
// definitions of vias found
struct SelectedViaDefinition
{
SelectedViaDefinition ()
: lib (0), pcell (0)
{ }
SelectedViaDefinition (db::Library *_lib, db::pcell_id_type _pcell, const db::ViaType &_via_type)
: lib (_lib), pcell (_pcell), via_type (_via_type)
{ }
db::Library *lib;
db::pcell_id_type pcell;
db::ViaType via_type;
};
std::vector<SelectedViaDefinition> via_defs;
// Find vias with corresponding top an bottom layers
// @@@ TODO: move elsewhere
for (auto l = db::LibraryManager::instance ().begin (); l != db::LibraryManager::instance ().end (); ++l) {
db::Library *lib = db::LibraryManager::instance ().lib (l->second);
for (auto pc = lib->layout ().begin_pcells (); pc != lib->layout ().end_pcells (); ++pc) {
const db::PCellDeclaration *pcell = lib->layout ().pcell_declaration (pc->second);
auto via_types = pcell->via_types ();
for (auto vt = via_types.begin (); vt != via_types.end (); ++vt) {
if ((vt->bottom.log_equal (lp) && vt->bottom_wired) || (vt->top.log_equal (lp) && vt->top_wired)) {
via_defs.push_back (SelectedViaDefinition (lib, pc->second, *vt));
}
}
}
}
SelectedViaDefinition via_def;
db::SelectedViaDefinition via_def;
if (via_defs.size () == 0) {
@ -1578,8 +1565,7 @@ PathService::via ()
cell ().insert (db::CellInstArray (db::CellInst (via_cell), db::Trans (trans () * via_pos - db::Point ())));
tl::warn << "@@@1 " << via_def.via_type.name;
// @@@ switch layer ..
change_edit_layer (lp_new);
m_points.clear ();
m_points.push_back (via_pos);
@ -1588,6 +1574,18 @@ PathService::via ()
update_marker ();
}
void
PathService::push_segment (const db::Shape &shape, const db::Instance &instance)
{
// @@@
}
void
PathService::pop_segment ()
{
// @@@
}
bool
PathService::configure (const std::string &name, const std::string &value)
{

View File

@ -51,6 +51,7 @@ public:
protected:
void get_edit_layer ();
void change_edit_layer (const db::LayerProperties &lp);
const db::VCplxTrans &trans () const { return m_trans; }
unsigned int layer () const { return m_layer; }
@ -244,15 +245,29 @@ protected:
void config_finalize ();
private:
struct PathSegment
{
PathSegment () : layer (0), cv_index (0) { }
unsigned int layer;
int cv_index;
std::list<std::pair<std::string, std::string> > config;
db::Shape path_shape;
db::Instance via_instance;
};
std::vector <db::DPoint> m_points;
double m_width, m_bgnext, m_endext;
enum { Flush = 0, Square, Variable, Round } m_type;
bool m_needs_update;
db::DPoint m_last;
std::list<PathSegment> m_previous_segments;
void update_marker ();
db::Path get_path () const;
void set_last_point (const db::DPoint &p);
void push_segment (const db::Shape &shape, const db::Instance &instance);
void pop_segment ();
};
/**

View File

@ -31,8 +31,13 @@
#include "layCellView.h"
#include "layLayoutViewBase.h"
#include "layEditable.h"
#include "layEditorOptionsPages.h"
#include "tlException.h"
#if defined(HAVE_QT)
# include <QMessageBox>
#endif
namespace edt {
// -------------------------------------------------------------
@ -74,6 +79,80 @@ std::map<std::string, tl::Variant> pcell_parameters_from_string (const std::stri
return pm;
}
void
commit_recent (lay::LayoutViewBase *view)
{
#if defined(HAVE_QT)
lay::EditorOptionsPages *eo_pages = view->editor_options_pages ();
if (!eo_pages) {
return;
}
for (std::vector<lay::EditorOptionsPage *>::const_iterator op = eo_pages->pages ().begin (); op != eo_pages->pages ().end (); ++op) {
if ((*op)->active ()) {
(*op)->commit_recent (view);
}
}
#endif
}
void
config_recent_for_layer (lay::LayoutViewBase *view, const db::LayerProperties &lp, int cv_index)
{
#if defined(HAVE_QT)
lay::EditorOptionsPages *eo_pages = view->editor_options_pages ();
if (!eo_pages) {
return;
}
for (std::vector<lay::EditorOptionsPage *>::const_iterator op = eo_pages->pages ().begin (); op != eo_pages->pages ().end (); ++op) {
if ((*op)->active ()) {
(*op)->config_recent_for_layer (view, lp, cv_index);
}
}
#endif
}
bool
set_or_request_current_layer (lay::LayoutViewBase *view, const db::LayerProperties &lp, unsigned int cv_index)
{
#if defined(HAVE_QT)
bool ok = view->set_current_layer (cv_index, lp);
if (ok) {
return true;
}
if (! view->control_panel ()) {
return false;
}
const lay::CellView &cv = view->cellview (cv_index);
if (! cv.is_valid ()) {
return false;
}
if (QMessageBox::question (view->widget (), tr ("Create Layer"), tr ("Layer %1 does not exist yet. Create it now?").arg (tl::to_qstring (lp.to_string ()))) == QMessageBox::Yes) {
lay::LayerPropertiesNode lpn;
lpn.set_source (lay::ParsedLayerSource (lp, cv_index));
view->init_layer_properties (lpn);
view->transaction (tl::to_string (QObject::tr ("Create new layer")));
lay::LayerPropertiesConstIterator lpi = lay::LayerPropertiesConstIterator (& view->insert_layer (view->end_layers (), lpn));
view->set_current_layer (lpi);
lpi->realize_source ();
view->commit ();
return true;
}
return false;
#else
return true;
#endif
}
// -------------------------------------------------------------
// TransformationsVariants implementation
// for a lay::LayoutView

View File

@ -66,6 +66,25 @@ std::map<std::string, tl::Variant> pcell_parameters_from_string (const std::stri
bool
get_parameters_from_pcell_and_guiding_shapes (db::Layout *layout, db::cell_index_type cell_index, db::pcell_parameters_type &parameters_for_pcell);
/**
* @brief Commits the current configuration for the recently used configuration list
*/
void
commit_recent (lay::LayoutViewBase *view);
/**
* @brief Configure attributes for the most-recent entry with the given layer
*/
void
config_recent_for_layer (lay::LayoutViewBase *view, const db::LayerProperties &lp, int cv_index);
/**
* @brief Request to make the given layer the current one (asks whether to create the layer if needed)
*/
bool
set_or_request_current_layer (lay::LayoutViewBase *view, const db::LayerProperties &lp, unsigned int cv_index);
/**
* @brief A helper class that identifies clipboard data for edt::
*/