diff --git a/src/edt/edt/MakeArrayOptionsDialog.ui b/src/edt/edt/MakeArrayOptionsDialog.ui
index 25e43bdb3..cb5778d8d 100644
--- a/src/edt/edt/MakeArrayOptionsDialog.ui
+++ b/src/edt/edt/MakeArrayOptionsDialog.ui
@@ -6,8 +6,8 @@
0
0
- 561
- 323
+ 586
+ 431
@@ -20,32 +20,6 @@
9
- -
-
-
- The selection will be copied row * columns times. Each copy will be displaced by a vector given by the row vector times the row index and the column vector times the column index.
-
-
- true
-
-
-
- -
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 10
-
-
-
-
-
@@ -61,144 +35,248 @@
false
-
- 9
-
6
-
-
-
-
-
- 1
- 0
-
+
-
+
+
+ 1
+
+
+ Array with pitch vectors
+
+
+
-
+
+
+ Each copy will be displaced by a vector given by the row vector times the row index and the column vector times the column index.
+
+
+ true
+
+
+
+ -
+
+
+ y =
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 1
+ 0
+
+
+
+
+ -
+
+
+ Column vector (x,y)
+
+
+
+ -
+
+
+ x =
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 1
+ 0
+
+
+
+
+ -
+
+
+
+ 1
+ 0
+
+
+
+
+ -
+
+
+ x =
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ y =
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 1
+ 0
+
+
+
+
+ -
+
+
+ Row vector (x,y)
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+ Array with space
+
+
+ -
+
+
+ Space
+
+
+
+ -
+
+
+
+ 1
+ 0
+
+
+
+
+ -
+
+
+
+ 1
+ 0
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 30
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ horizonal =
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ vertical =
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ Use visible layers only for bounding boxes of instances
+
+
+
+ -
+
+
+ The selection is placed in a rectangular array, with the bounding box defining the pitch. Additional space can be added between columns and rows.
+
+
+ true
+
+
+
+
+
- -
-
+
-
+
- x =
+ The selection will be copied row * columns times.
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+ true
- -
-
-
-
- 1
- 0
-
-
-
-
- -
-
-
- Columns =
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
- Rows =
-
-
-
- -
-
-
-
- 1
- 0
-
-
-
-
- -
-
-
- Row vector (x,y)
-
-
-
- -
-
-
- Column vector (x,y)
-
-
-
- -
-
-
-
- 1
- 0
-
-
-
-
- -
-
-
- x =
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
-
- 1
- 0
-
-
-
-
- -
-
-
-
- 1
- 0
-
-
-
-
- -
-
-
- y =
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
- y =
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
+
-
Qt::Vertical
@@ -214,6 +292,59 @@
+ -
+
+
+ Columns =
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 1
+ 0
+
+
+
+
+ -
+
+
+ Rows =
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 1
+ 0
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
@@ -271,10 +402,14 @@
columns_le
rows_le
+ mode_tab
column_x_le
column_y_le
row_x_le
row_y_le
+ space_x_le
+ space_y_le
+ vis_only_cbx
diff --git a/src/edt/edt/edtDialogs.cc b/src/edt/edt/edtDialogs.cc
index 0e127f5bb..8a4d8873d 100644
--- a/src/edt/edt/edtDialogs.cc
+++ b/src/edt/edt/edtDialogs.cc
@@ -26,6 +26,7 @@
#include "dbLayout.h"
#include "edtDialogs.h"
+#include "edtMainService.h"
#include "layEditorUtils.h"
#include "layObjectInstPath.h"
#include "layCellView.h"
@@ -646,29 +647,41 @@ MakeArrayOptionsDialog::MakeArrayOptionsDialog (QWidget *parent)
}
bool
-MakeArrayOptionsDialog::exec_dialog (db::DVector &a, unsigned int &na, db::DVector &b, unsigned int &nb)
+MakeArrayOptionsDialog::exec_dialog (ArrayOptions &options)
{
- rows_le->setText (tl::to_qstring (tl::to_string (na)));
- columns_le->setText (tl::to_qstring (tl::to_string (nb)));
- row_x_le->setText (tl::to_qstring (tl::micron_to_string (a.x ())));
- row_y_le->setText (tl::to_qstring (tl::micron_to_string (a.y ())));
- column_x_le->setText (tl::to_qstring (tl::micron_to_string (b.x ())));
- column_y_le->setText (tl::to_qstring (tl::micron_to_string (b.y ())));
+ rows_le->setText (tl::to_qstring (tl::to_string (options.na)));
+ columns_le->setText (tl::to_qstring (tl::to_string (options.nb)));
+ row_x_le->setText (tl::to_qstring (tl::micron_to_string (options.a.x ())));
+ row_y_le->setText (tl::to_qstring (tl::micron_to_string (options.a.y ())));
+ column_x_le->setText (tl::to_qstring (tl::micron_to_string (options.b.x ())));
+ column_y_le->setText (tl::to_qstring (tl::micron_to_string (options.b.y ())));
+ space_x_le->setText (tl::to_qstring (tl::micron_to_string (options.space.x ())));
+ space_y_le->setText (tl::to_qstring (tl::micron_to_string (options.space.y ())));
+
+ mode_tab->setCurrentIndex (options.mode == ArrayOptions::PitchVectors ? 0 : 1);
+ vis_only_cbx->setChecked (options.use_visible_layers);
if (QDialog::exec ()) {
+ options.mode = mode_tab->currentIndex () == 0 ? ArrayOptions::PitchVectors : ArrayOptions::Spaced;
+ options.use_visible_layers = vis_only_cbx->isChecked ();
+
double bx = 0.0, by = 0.0;
double ax = 0.0, ay = 0.0;
+ double sx = 0.0, sy = 0.0;
tl::from_string_ext (tl::to_string (column_x_le->text ()), bx);
tl::from_string_ext (tl::to_string (column_y_le->text ()), by);
- tl::from_string_ext (tl::to_string (columns_le->text ()), nb);
+ tl::from_string_ext (tl::to_string (columns_le->text ()), options.nb);
tl::from_string_ext (tl::to_string (row_x_le->text ()), ax);
tl::from_string_ext (tl::to_string (row_y_le->text ()), ay);
- tl::from_string_ext (tl::to_string (rows_le->text ()), na);
+ tl::from_string_ext (tl::to_string (rows_le->text ()), options.na);
+ tl::from_string_ext (tl::to_string (space_x_le->text ()), sx);
+ tl::from_string_ext (tl::to_string (space_y_le->text ()), sy);
- a = db::DVector (ax, ay);
- b = db::DVector (bx, by);
+ options.a = db::DVector (ax, ay);
+ options.b = db::DVector (bx, by);
+ options.space = db::DVector (sx, sy);
return true;
@@ -758,7 +771,7 @@ popup_tap_layer_menu (lay::LayoutViewBase *view, const std::set > layers_in_selection;
for (lay::ShapeFinder::iterator f = finder.begin (); f != finder.end (); ++f) {
- if (cv_index < 0 || f->cv_index () == cv_index) {
+ if (cv_index < 0 || int (f->cv_index ()) == cv_index) {
const db::Layout &ly = view->cellview (f->cv_index ())->layout ();
// ignore guiding shapes and only provide layers from the filter
if (f->layer () != ly.guiding_shape_layer ()
diff --git a/src/edt/edt/edtDialogs.h b/src/edt/edt/edtDialogs.h
index b1de5961b..bb288d556 100644
--- a/src/edt/edt/edtDialogs.h
+++ b/src/edt/edt/edtDialogs.h
@@ -56,6 +56,8 @@ namespace lay
namespace edt {
+class ArrayOptions;
+
/**
* @brief The copy mode dialog
*/
@@ -173,10 +175,10 @@ class MakeArrayOptionsDialog
private Ui::MakeArrayOptionsDialog
{
Q_OBJECT
-
public:
+
MakeArrayOptionsDialog (QWidget *parent);
- bool exec_dialog (db::DVector &a, unsigned int &na, db::DVector &b, unsigned int &nb);
+ bool exec_dialog (ArrayOptions &options);
virtual void accept ();
};
diff --git a/src/edt/edt/edtMainService.cc b/src/edt/edt/edtMainService.cc
index 2187b574d..f2331e109 100644
--- a/src/edt/edt/edtMainService.cc
+++ b/src/edt/edt/edtMainService.cc
@@ -81,8 +81,6 @@ MainService::MainService (db::Manager *manager, lay::LayoutViewBase *view, lay::
m_distribute_vmode (1), m_distribute_vpitch (0.0), m_distribute_vspace (0.0),
m_distribute_visible_layers (false),
m_origin_mode_x (-1), m_origin_mode_y (-1), m_origin_visible_layers_for_bbox (false),
- m_array_a (0.0, 1.0), m_array_b (1.0, 0.0),
- m_array_na (1), m_array_nb (1),
m_router (0.0), m_rinner (0.0), m_npoints (64), m_undo_before_apply (true)
{
#if defined(HAVE_QT)
@@ -2251,32 +2249,66 @@ MainService::cm_make_array ()
tl_assert (false); // see TODO
#endif
- size_t n = 0;
check_no_guiding_shapes ();
std::vector edt_services = view ()->get_plugins ();
- for (std::vector::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
- for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
- ++n;
- }
+ bool any = false;
+ for (std::vector::const_iterator es = edt_services.begin (); es != edt_services.end () && ! any; ++es) {
+ any = ! (*es)->begin_selection ().at_end ();
}
-
- if (n == 0) {
+ if (! any) {
throw tl::Exception (tl::to_string (tr ("Nothing selected to make arrays of")));
}
#if defined(HAVE_QT)
// TODO: make parameters persistent so we can set them externally
- if (! make_array_options_dialog ()->exec_dialog (m_array_a, m_array_na, m_array_b, m_array_nb)) {
+ if (! make_array_options_dialog ()->exec_dialog (m_array_options)) {
return;
}
#endif
+ unsigned int na = m_array_options.na;
+ unsigned int nb = m_array_options.nb;
+ db::DVector a = m_array_options.a;
+ db::DVector b = m_array_options.b;
+
+ if (m_array_options.mode == ArrayOptions::Spaced) {
+
+ db::DBox bbox;
+
+ // get the selection bbox
+ for (std::vector::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
+ for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
+
+ const db::Layout &layout = view ()->cellview (s->cv_index ())->layout ();
+ db::CplxTrans tr = db::CplxTrans (layout.dbu ()) * s->trans ();
+
+ if (! s->is_cell_inst ()) {
+ bbox += tr * s->shape ().bbox ();
+ } else {
+ bbox += inst_bbox (tr, view (), s->cv_index (), s->back (), m_array_options.use_visible_layers);
+ }
+
+ }
+ }
+
+ // compute pitch vectors
+ a = db::DVector (0.0, m_array_options.space.y () + bbox.height ()); // row-pitch
+ b = db::DVector (m_array_options.space.x () + bbox.width (), 0.0); // column-pitch
+
+ }
+
+ make_array (na, nb, a, b);
+}
+
+void
+MainService::make_array (unsigned int na, unsigned int nb, const db::DVector &a, const db::DVector &b)
+{
view ()->cancel_edits ();
// undo support for small arrays only
- bool has_undo = (m_array_na * m_array_nb < 1000);
+ bool has_undo = (na * nb < 1000);
// No undo support currently - the undo buffering is pretty inefficient right now.
if (manager ()) {
@@ -2287,7 +2319,17 @@ MainService::cm_make_array ()
}
}
- tl::RelativeProgress progress (tl::to_string (tr ("Make array")), (size_t (m_array_na) * size_t (m_array_nb) - 1) * n, 1000);
+ std::vector edt_services = view ()->get_plugins ();
+
+ // count selected items for progress
+ size_t n = 0;
+ for (std::vector::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
+ for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
+ ++n;
+ }
+ }
+
+ tl::RelativeProgress progress (tl::to_string (tr ("Make array")), (size_t (na) * size_t (nb) - 1) * n, 1000);
for (std::vector::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
@@ -2302,15 +2344,15 @@ MainService::cm_make_array ()
if (s->is_cell_inst ()) {
- for (unsigned int ia = 0; ia < m_array_na; ++ia) {
- for (unsigned int ib = 0; ib < m_array_nb; ++ib) {
+ for (unsigned int ia = 0; ia < na; ++ia) {
+ for (unsigned int ib = 0; ib < nb; ++ib) {
// don't create a copy
if (ia == 0 && ib == 0) {
continue;
}
- db::DCplxTrans dtrans (m_array_a * double (ia) + m_array_b * double (ib));
+ db::DCplxTrans dtrans (a * double (ia) + b * double (ib));
db::ICplxTrans itrans (db::DCplxTrans (s->trans ()).inverted () * db::DCplxTrans (1.0 / cv->layout ().dbu ()) * dtrans * db::DCplxTrans (cv->layout ().dbu ()) * db::DCplxTrans (s->trans ()));
db::Instance new_inst = target_cell.insert (s->back ().inst_ptr);
@@ -2326,15 +2368,15 @@ MainService::cm_make_array ()
db::Shapes &target_shapes = target_cell.shapes (s->layer ());
- for (unsigned int ia = 0; ia < m_array_na; ++ia) {
- for (unsigned int ib = 0; ib < m_array_nb; ++ib) {
+ for (unsigned int ia = 0; ia < na; ++ia) {
+ for (unsigned int ib = 0; ib < nb; ++ib) {
// don't create a copy
if (ia == 0 && ib == 0) {
continue;
}
- db::DCplxTrans dtrans (m_array_a * double (ia) + m_array_b * double (ib));
+ db::DCplxTrans dtrans (a * double (ia) + b * double (ib));
db::ICplxTrans itrans (db::DCplxTrans (s->trans ()).inverted () * db::DCplxTrans (1.0 / cv->layout ().dbu ()) * dtrans * db::DCplxTrans (cv->layout ().dbu ()) * db::DCplxTrans (s->trans ()));
db::Shape new_shape = target_shapes.insert (s->shape ());
diff --git a/src/edt/edt/edtMainService.h b/src/edt/edt/edtMainService.h
index 34820fbca..773de00b1 100644
--- a/src/edt/edt/edtMainService.h
+++ b/src/edt/edt/edtMainService.h
@@ -56,6 +56,21 @@ class DistributeOptionsDialog;
// -------------------------------------------------------------
+struct ArrayOptions
+{
+ enum mode_type { PitchVectors, Spaced };
+
+ ArrayOptions () : mode (PitchVectors), a (0.0, 1.0), b (1.0, 0.0), na (1), nb (1) { }
+
+ mode_type mode;
+ db::DVector a, b;
+ unsigned int na, nb;
+ db::DVector space;
+ bool use_visible_layers;
+};
+
+// -------------------------------------------------------------
+
class MainService
: public lay::Plugin,
public lay::Editable,
@@ -155,6 +170,11 @@ public:
*/
void cm_make_array ();
+ /**
+ * @brief The parameterized function for making arrays
+ */
+ void make_array (unsigned na, unsigned nb, const db::DVector &a, const db::DVector &b);
+
/**
* @brief Align the selected shapes and instances
*/
@@ -242,11 +262,11 @@ private:
std::string m_make_cell_name;
int m_origin_mode_x, m_origin_mode_y;
bool m_origin_visible_layers_for_bbox;
- db::DVector m_array_a, m_array_b;
- unsigned int m_array_na, m_array_nb;
double m_router, m_rinner;
unsigned int m_npoints;
bool m_undo_before_apply;
+ ArrayOptions m_array_options;
+
#if defined(HAVE_QT)
edt::RoundCornerOptionsDialog *mp_round_corners_dialog;
edt::AreaAndPerimeterDialog *mp_area_and_perimeter_dialog;
diff --git a/src/layui/layui/AlignCellOptionsDialog.ui b/src/layui/layui/AlignCellOptionsDialog.ui
index 637bdd8b2..9b5d4bf13 100644
--- a/src/layui/layui/AlignCellOptionsDialog.ui
+++ b/src/layui/layui/AlignCellOptionsDialog.ui
@@ -6,8 +6,8 @@
0
0
- 432
- 349
+ 449
+ 370
@@ -405,6 +405,13 @@
+ -
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
-
@@ -429,44 +436,12 @@
0
-
-
-
-
- Qt::Horizontal
-
-
-
- 209
- 20
-
-
-
-
- -
-
-
- Ok
-
-
- true
-
-
-
- -
-
-
- Cancel
-
-
-
- pushButton
- pushButton_2
lt
ct
rt
@@ -486,34 +461,34 @@
- pushButton
- clicked()
+ buttonBox
+ accepted()
AlignCellOptionsDialog
accept()
- 237
- 203
+ 224
+ 295
- 147
- 81
+ 224
+ 176
- pushButton_2
- clicked()
+ buttonBox
+ rejected()
AlignCellOptionsDialog
reject()
- 325
- 202
+ 224
+ 295
- 325
- 57
+ 224
+ 176