From 07966baf717d8fda68fbd7cab693880239234f21 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Fri, 5 Mar 2021 18:20:45 +0100 Subject: [PATCH] First draft of fill dialog with enhancements --- src/db/db/dbFillTool.cc | 5 +- src/lay/lay/FillDialog.ui | 1543 ++++++++++++++++++++-------------- src/lay/lay/layFillDialog.cc | 57 +- 3 files changed, 980 insertions(+), 625 deletions(-) diff --git a/src/db/db/dbFillTool.cc b/src/db/db/dbFillTool.cc index ce9126e21..a9024b201 100644 --- a/src/db/db/dbFillTool.cc +++ b/src/db/db/dbFillTool.cc @@ -388,10 +388,11 @@ compute_shear_matrix (const db::Vector &r, const db::Vector &c) double det = r.x () * c.y () - r.y () * c.x (); double m11 = c.y () * r.x () / det; + double m22 = m11; double m12 = -c.x () * r.x () / det; - double m22 = c.y () * r.x () / det; + double m21 = -c.y () * r.y () / det; - return IMatrix2d (m11, m12, m12, m22); + return IMatrix2d (m11, m12, m21, m22); } DB_PUBLIC bool diff --git a/src/lay/lay/FillDialog.ui b/src/lay/lay/FillDialog.ui index c523ef32b..a5ad360b7 100644 --- a/src/lay/lay/FillDialog.ui +++ b/src/lay/lay/FillDialog.ui @@ -1,693 +1,981 @@ - + + FillDialog - - + + 0 0 - 681 - 773 + 691 + 437 - + Fill Tool - - - 9 - - + + 6 + + 9 + + + 9 + + + 9 + + + 9 + - - - Fill Area + + + 0 - - - 9 - - - 6 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 0 + + + Fill Area + + + + + + + 0 + 0 + - - 6 - - - - - Select how the region to fill is specified. - - - - All (whole cell) - - - - - Shapes on layer ... - - - - - Selected shapes - - - - - Single box with ... - - - - - Ruler bounding boxes - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - - - - - + + 0 - + + 0 + + + 0 + + + 0 + + 6 - - - - Qt::Vertical + + + + QFrame::NoFrame - - - 241 - 40 - + + QFrame::Raised - + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Select how the region to fill is specified. + + + + All (whole cell) + + + + + Shapes on layer ... + + + + + Selected shapes + + + + + Single box with ... + + + + + Ruler bounding boxes + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + - + - + Qt::Horizontal - + - 121 + 40 20 - - - - true + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Keep distance to border of fill area of + + + + + + + + 0 + 0 + + + + Leave empty for no distance. Otherwise enter a distance in micron (can be anisotropic in the form "dx,dy") + + + + + + + µm + + + + + + + + + + + + + 1 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 6 + + + + + Qt::Vertical + + + + 241 + 40 + + + + + + + + Qt::Horizontal + + + + 121 + 20 + + + + + + + + true + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 6 + + + + + true + + + Box Boundaries + + + + 9 + + + 9 + + + 9 + + + 9 + + + 6 + + + + + y = + + + + + + + 1st corner + + + + + + + + + + y = + + + + + + + + + + x = + + + + + + + + + + 2nd corner + + + + + + + + + + x = + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Exclude Areas + + + + + + + 0 + 0 + + + + Leave empty for no distance. Otherwise enter a distance in micron (can be anisotropic in the form "dx,dy") + + + + + + + µm + + + + + + + Spacing around exclude areas + + + + + + + The fill will not be generated over the areas specified by these layers + + + + All layers + + + + + All visible layers + + + + + Selected layers + + + + + No exclude + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 15 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 309 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + Fill Cell + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 6 + + + + + µm (keep distance between fill cells unless stitched) + + + + + + + Fill cell margin + + + + + + + Qt::Horizontal + + + + 171 + 23 + + + + + + + + + 0 + 0 + + + + This layer defines the borders of the fill cell. The fill cells will be stiched seamlessly at this border + + + QComboBox::AdjustToContents + + + + + + + Select the cell which will be used as tiling cell for the fill area + + + + + + + (for aligning the fill cell and default tile raster) + + + + + + + Step vectors + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + 0 + 0 + + + + Boundary layer + + + + + + + + 0 + 0 + + + + Fill cell + + + + + + + + 0 + 0 + + + + Leave empty for no distance. Otherwise enter a distance in micron (can be anisotropic in the form "dx,dy") + + + + + + + Qt::Horizontal + + + + 171 + 20 + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + Row + + + + + + + (dx, dy in µm) + + + + + + + (dx, dy in µm) + + + + + + + Column + + + + + + + By default, the step vectors are given by the bounding box width (row dx) and height (column dy) of the fill cell or the boundary layer - if one is given. + + + true + + + + + + + + + + + + + ... - - - - 0 - - + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + + Options + + + + + + 6 - - - + + 0 + + + 0 + + + 0 + + + 0 + + + + + Enhanced fill (leave fixed raster to enhance fill of small regions) + + + + + + + Second-order fill cell for remaining regions + + true - - Box Boundaries + + false - - + + 9 - + + 9 + + + 9 + + + 9 + + 6 - - - - y = + + + + µm (keep distance between fill cells unless stitched) - - - - 2nd corner + + + + Specify the fill cell for the secondary fill analogous to the primary fill cell - - - - x = + + + + + 0 + 0 + + + + Leave empty for no distance. Otherwise enter a distance in micron (can be anisotropic in the form "dx,dy") - - - - 1st corner + + + + ... - - - - x = + + + + Qt::Horizontal + + + + 141 + 20 + + + + + + + + Fill cell margin - - - - y = + + + + + 0 + 0 + + + + Fill cell - - + + + + The second order fill cell is used to fill space remaining from the first fill step. Thus, the second order fill cell must be smaller than the first order fill cell. The boundary layer must be the same for the second order fill cell. + + + true + + - - + + + + Step vectors + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + - - - - - + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Row + + + + + + + (dx, dy in µm) + + + + + + + (dx, dy in µm) + + + + + + + By default, the step vectors are given by the bounding box width (row dx) and height (column dy) of the fill cell or the boundary layer - if one is given. + + + true + + + + + + + + + + Column + + + + + + + + - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 0 + + + + + Qt::Vertical - - 6 + + + 20 + 40 + - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 0 - - - 6 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Keep distance to border of fill area of - - - - - - - - 5 - 0 - 0 - 0 - - - - Leave empty for no distance. Otherwise enter a distance in micron (can be anisotropic in the form "dx,dy") - - - - - - - µm - - - - - - - - - - + + + + - - - Exclude Areas - - - - 9 - - - 6 - - - - - The fill will not be generated over the areas specified by these layers - - - - All layers - - - - - All visible layers - - - - - Selected layers - - - - - No exclude - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Spacing around exclude areas - - - - - - - - 5 - 0 - 0 - 0 - - - - Leave empty for no distance. Otherwise enter a distance in micron (can be anisotropic in the form "dx,dy") - - - - - - - µm - - - - - - - - - - Fill Cell - - - - 9 - - - 6 - - - - - Fill cell margin - - - - - - - - 5 - 5 - 0 - 0 - - - - This layer defines the borders of the fill cell. The fill cells will be stiched seamlessly at this border - - - QComboBox::AdjustToContents - - - - - - - - 5 - 0 - 0 - 0 - - - - Leave empty for no distance. Otherwise enter a distance in micron (can be anisotropic in the form "dx,dy") - - - - - - - µm - - - - - - - Qt::Horizontal - - - - 171 - 20 - - - - - - - - Qt::Horizontal - - - - 171 - 23 - - - - - - - - (controls tiling raster of the cells) - - - - - - - - 0 - 5 - 0 - 0 - - - - Boundary layer - - - - - - - ... - - - - - - - Select the cell which will be used as tiling cell for the fill area - - - - - - - - 1 - 5 - 0 - 0 - - - - Fill cell - - - - - - - - - - Options - - - - 9 - - - 6 - - - - - Enhanced fill (leave fixed raster to enhance fill of small regions) - - - - - - - Second-order fill cell for remaining regions - - - true - - - false - - - - 9 - - - 6 - - - - - - 1 - 5 - 0 - 0 - - - - Fill cell - - - - - - - Specify the fill cell for the secondary fill analogous to the primary fill cell - - - - - - - ... - - - - - - - Qt::Horizontal - - - - 141 - 20 - - - - - - - - µm - - - - - - - - 5 - 0 - 0 - 0 - - - - Leave empty for no distance. Otherwise enter a distance in micron (can be anisotropic in the form "dx,dy") - - - - - - - Fill cell margin - - - - - - - The second order fill cell is used to fill space remaining from the first fill step. Thus, the second order fill cell must be smaller than the first order fill cell. The boundary layer must be the same for the second order fill cell. - - - true - - - - - - - - - - - - - Qt::Vertical - - - - 623 - 20 - - - - - - - + + Qt::Horizontal - - QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok @@ -701,12 +989,29 @@ + tabWidget + fill_area_cbx cb_layer le_x1 le_y1 le_x2 le_y2 - button_box + distance_le + layer_spec_cbx + exclude_le + fill_cell_le + choose_fc_pb + fill_margin_le + fc_boundary_layer + row_le + column_le + enhanced_cb + second_order_fill_cb + fill_cell_2nd_le + choose_fc_2nd_pb + fill2_margin_le + row_2nd_le + column_2nd_le @@ -716,11 +1021,11 @@ FillDialog accept() - + 248 254 - + 157 274 @@ -732,11 +1037,11 @@ FillDialog reject() - + 316 260 - + 286 274 diff --git a/src/lay/lay/layFillDialog.cc b/src/lay/lay/layFillDialog.cc index dff0a42e2..6503a453c 100644 --- a/src/lay/lay/layFillDialog.cc +++ b/src/lay/lay/layFillDialog.cc @@ -83,6 +83,8 @@ FillDialog::FillDialog (lay::Dispatcher *main, lay::LayoutView *view) Ui::FillDialog::setupUi (this); + fc_boundary_layer->set_no_layer_available (true); + fill_area_stack->setCurrentIndex (0); connect (fill_area_cbx, SIGNAL (currentIndexChanged (int)), this, SLOT (fill_area_changed (int))); connect (button_box, SIGNAL (accepted ()), this, SLOT (ok_pressed ())); @@ -274,17 +276,37 @@ BEGIN_PROTECTED const db::Cell *fill_cell = &cv->layout ().cell (fc.second); int fc_bbox_layer = fc_boundary_layer->current_layer (); - if (fc_bbox_layer < 0 || ! cv->layout ().is_valid_layer (fc_bbox_layer)) { + if (fc_bbox_layer >= 0 && ! cv->layout ().is_valid_layer (fc_bbox_layer)) { throw tl::Exception (tl::to_string (QObject::tr ("No valid layer selected to get fill cell's bounding box from"))); } - db::Box fc_bbox = fill_cell->bbox (fc_bbox_layer); + db::Box fc_bbox = fc_bbox_layer < 0 ? fill_cell->bbox () : fill_cell->bbox (fc_bbox_layer); if (fc_bbox.empty ()) { throw tl::Exception (tl::to_string (QObject::tr ("No valid layer selected to get fill cell's bounding box from - layer is empty for the fill cell"))); } + db::Coord row_dx = fc_bbox.width (), row_dy = 0; + db::Coord column_dx = 0.0, column_dy = fc_bbox.height (); + + s = tl::to_string (row_le->text ()); + ex = tl::Extractor (s.c_str ()); + if (ex.try_read (x) && ex.test (",") && ex.try_read (y)) { + row_dx = db::coord_traits::rounded (x / cv->layout ().dbu ()); + row_dy = db::coord_traits::rounded (y / cv->layout ().dbu ()); + } + + s = tl::to_string (column_le->text ()); + ex = tl::Extractor (s.c_str ()); + if (ex.try_read (x) && ex.test (",") && ex.try_read (y)) { + column_dx = db::coord_traits::rounded (x / cv->layout ().dbu ()); + column_dy = db::coord_traits::rounded (y / cv->layout ().dbu ()); + } + bool enhanced_fill = enhanced_cb->isChecked (); + double row_dx2 = 0.0, row_dy2 = 0.0; + double column_dx2 = 0.0, column_dy2 = 0.0; + const db::Cell *fill_cell2 = 0; db::Box fc_bbox2; @@ -297,11 +319,30 @@ BEGIN_PROTECTED fill_cell2 = &cv->layout ().cell (fc.second); - fc_bbox2 = fill_cell2->bbox (fc_bbox_layer); + fc_bbox2 = fc_bbox_layer < 0 ? fill_cell2->bbox () : fill_cell2->bbox (fc_bbox_layer); if (fc_bbox2.empty ()) { throw tl::Exception (tl::to_string (QObject::tr ("Second order fill cell is empty for the given boundary layer"))); } + row_dx2 = fc_bbox2.width (); + row_dy2 = 0; + column_dx2 = 0.0; + column_dy2 = fc_bbox2.height (); + + s = tl::to_string (row_2nd_le->text ()); + ex = tl::Extractor (s.c_str ()); + if (ex.try_read (x) && ex.test (",") && ex.try_read (y)) { + row_dx2 = db::coord_traits::rounded (x / cv->layout ().dbu ()); + row_dy2 = db::coord_traits::rounded (y / cv->layout ().dbu ()); + } + + s = tl::to_string (column_2nd_le->text ()); + ex = tl::Extractor (s.c_str ()); + if (ex.try_read (x) && ex.test (",") && ex.try_read (y)) { + column_dx2 = db::coord_traits::rounded (x / cv->layout ().dbu ()); + column_dy2 = db::coord_traits::rounded (y / cv->layout ().dbu ()); + } + } if (tl::verbosity () >= 20) { @@ -483,7 +524,10 @@ BEGIN_PROTECTED tl::info << "Compute fill for one region :" << fp0->to_string (); } - bool any_fill = fill_region (cv.cell (), *fp0, fill_cell->cell_index (), fc_bbox, fr_bbox.p1 (), enhanced_fill, (enhanced_fill || fill_cell2) ? &new_fill_area : 0, fill_margin); + db::Vector rs (row_dx, row_dy), cs (column_dx, column_dy); + db::Vector ko = fc_bbox.center () - db::Point () - (rs + cs) / 2; + + bool any_fill = fill_region (cv.cell (), *fp0, fill_cell->cell_index (), ko, rs, cs, fr_bbox.center (), enhanced_fill, (enhanced_fill || fill_cell2) ? &new_fill_area : 0, fill_margin); if (! any_fill) { non_filled_area.push_back (*fp0); } @@ -506,6 +550,11 @@ BEGIN_PROTECTED fc_bbox = fc_bbox2; fill_margin = fill2_margin; + row_dx = row_dx2; + row_dy = row_dy2; + column_dx = column_dx2; + column_dy = column_dy2; + fill_cell2 = 0; fc_bbox2 = db::Box ();