Merge branch 'issue-306'

This commit is contained in:
Matthias Koefferlein 2019-08-19 00:03:39 +02:00
commit fe4396d872
8 changed files with 342 additions and 99 deletions

View File

@ -858,6 +858,7 @@ do_extract_rad_from_contour (typename db::polygon<C>::polygon_contour_iterator f
typename db::polygon<C>::polygon_contour_iterator p2 = p1;
const double cos_thr = 0.8;
const double acute_cos_thr = -0.8;
const double circle_segment_thr = 2.5;
// search for the first circle segment (where cos(a) > cos_thr)
@ -1031,7 +1032,7 @@ do_extract_rad_from_contour (typename db::polygon<C>::polygon_contour_iterator f
if (in_corner) {
std::pair<bool, db::point<C> > cp = elast.cut_point (e);
if (! cp.first) {
if (! cp.first || db::sprod (elast, e) < acute_cos_thr * elast.double_length () * e.double_length ()) {
// We have a full 180 degree bend without a stop (actually two corners).
// Use the segment in between that is perpendicular to the start and end segment as stop edge.
@ -1048,7 +1049,7 @@ do_extract_rad_from_contour (typename db::polygon<C>::polygon_contour_iterator f
}
e = db::edge<C> (*pp1, *pp2);
if (db::sprod_sign (elast, e) == 0) {
if (db::sprod_sign (elast, e) <= 0) {
break;
}
@ -1059,6 +1060,13 @@ do_extract_rad_from_contour (typename db::polygon<C>::polygon_contour_iterator f
}
++nseg_part;
if (nseg_part >= nseg) {
// not a valid rounded bend - skip this solution
return false;
}
cp = elast.cut_point (e);
if (! cp.first) {
return false;
@ -1068,8 +1076,6 @@ do_extract_rad_from_contour (typename db::polygon<C>::polygon_contour_iterator f
new_pts->push_back (cp.second);
}
++nseg_part;
asum -= asum_part;
asum -= db::vprod (e.p1 () - db::point<C> (), e.p2 () - db::point<C> ());
nseg -= nseg_part;

View File

@ -1555,6 +1555,120 @@ TEST(204)
EXPECT_EQ (pr.to_string (), "(0,0;0,40000;40000,40000;40000,0/10000,10000;30000,10000;30000,30000;10000,30000)");
}
// rounding
TEST(205_issue318)
{
db::Point pattern [] = {
db::Point (0, 0),
db::Point (0, 420000),
db::Point (400000, 400000),
db::Point (400000, 0),
};
db::Polygon p;
p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0]));
double rinner = 0.0, router = 0.0;
unsigned int n;
db::Polygon pr;
db::Polygon pp = compute_rounded (p, 100000, 200000, 64);
EXPECT_EQ (extract_rad (pp, rinner, router, n, &pr), true);
EXPECT_EQ (tl::to_string (rinner), "0");
EXPECT_EQ (tl::to_string (router), "200000");
EXPECT_EQ (tl::to_string (n), "64");
// slight rounding errors, but still a good approximation ...
EXPECT_EQ (pr.to_string (), "(0,0;0,419998;400000,400002;400000,0)");
pp = compute_rounded (p, 50000, 100000, 64);
EXPECT_EQ (extract_rad (pp, rinner, router, n, &pr), true);
EXPECT_EQ (tl::to_string (rinner), "0");
EXPECT_EQ (tl::to_string (router), "100000");
EXPECT_EQ (tl::to_string (n), "64");
// slight rounding issue due to ...
EXPECT_EQ (pr.to_string (), "(0,0;0,420001;400000,400000;400000,0)");
}
// rounding
TEST(206_issue318)
{
db::Point pattern [] = {
db::Point (0, 0),
db::Point (0, 40000000),
db::Point (400000, 400000),
db::Point (400000, 0),
};
db::Polygon p;
p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0]));
double rinner = 0.0, router = 0.0;
unsigned int n;
db::Polygon pr;
db::Polygon pp = compute_rounded (p, 100000, 200000, 64);
EXPECT_EQ (extract_rad (pp, rinner, router, n, &pr), true);
EXPECT_EQ (tl::to_string (rinner), "0");
EXPECT_EQ (tl::to_string (router), "199992");
EXPECT_EQ (tl::to_string (n), "65");
// good approximation of a top edge ...
EXPECT_EQ (pr.to_string (), "(0,0;0,618467;400000,581242;400000,0)");
pp = compute_rounded (p, 50000, 100000, 64);
EXPECT_EQ (extract_rad (pp, rinner, router, n, &pr), true);
EXPECT_EQ (tl::to_string (rinner), "0");
EXPECT_EQ (tl::to_string (router), "100000");
EXPECT_EQ (tl::to_string (n), "64");
// the acute corner is split into two parts
EXPECT_EQ (pr.to_string (), "(0,0;0,20309228;199083,20290710;400000,400000;400000,0)");
}
// rounding
TEST(207_issue318)
{
db::Point pattern [] = {
db::Point(-2523825, -4693678),
db::Point(-2627783, -4676814),
db::Point(-2705532, -4629488),
db::Point(-2747861, -4559084),
db::Point(-2750596, -4499543),
db::Point(-2753284, -4335751),
db::Point(-2764621, -4271381),
db::Point(-2828260, -4154562),
db::Point(-2808940, -4144038),
db::Point(-2743579, -4264019),
db::Point(-2731316, -4333649),
db::Point(-2728604, -4498857),
db::Point(-2726139, -4552516),
db::Point(-2689468, -4613512),
db::Point(-2620017, -4655786),
db::Point(-2529175, -4670522),
db::Point(-2468652, -4627768),
db::Point(-2437469, -4536777),
db::Point(-2434902, -4384723),
db::Point(-2436252, -4320529),
db::Point(-2395450, -4234678),
db::Point(-2338494, -4144716),
db::Point(-2319906, -4156484),
db::Point(-2376150, -4245322),
db::Point(-2414148, -4325271),
db::Point(-2412898, -4384677),
db::Point(-2415531, -4540623),
db::Point(-2450148, -4641632)
};
db::Polygon p;
p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0]));
double rinner = 0.0, router = 0.0;
unsigned int n;
db::Polygon pr;
// this polygon should not be recognized as rounded - it kind of looks like ...
EXPECT_EQ (extract_rad (p, rinner, router, n, &pr), false);
}
// is_convex
TEST(300)
{

View File

@ -36,7 +36,6 @@ SOURCES = \
dbPCells.cc \
dbPoint.cc \
dbPolygon.cc \
dbPolygonTools.cc \
dbPropertiesRepository.cc \
dbRegion.cc \
dbShapeArray.cc \
@ -72,7 +71,8 @@ SOURCES = \
dbNetlistCompareTests.cc \
dbNetlistReaderTests.cc \
dbLayoutVsSchematicTests.cc \
dbLayoutQueryTests.cc
dbLayoutQueryTests.cc \
dbPolygonToolsTests.cc
INCLUDEPATH += $$TL_INC $$DB_INC $$GSI_INC
DEPENDPATH += $$TL_INC $$DB_INC $$GSI_INC

View File

@ -1,70 +1,78 @@
<ui version="4.0" >
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RoundCornerOptionsDialog</class>
<widget class="QDialog" name="RoundCornerOptionsDialog" >
<property name="geometry" >
<widget class="QDialog" name="RoundCornerOptionsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>469</width>
<height>241</height>
<height>271</height>
</rect>
</property>
<property name="windowTitle" >
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout" >
<item row="2" column="1" >
<widget class="QLineEdit" name="router_le" />
</item>
<item row="2" column="0" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>Outer corner radius</string>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0" colspan="3">
<widget class="QCheckBox" name="amend_cb">
<property name="text">
<string>Amend mode (undo existing rounding before applying new one)</string>
</property>
</widget>
</item>
<item row="5" column="0" >
<widget class="QLabel" name="label_2" >
<property name="text" >
<item row="7" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Number of points (for full circle)</string>
</property>
</widget>
</item>
<item row="3" column="0" >
<widget class="QLabel" name="label_3" >
<property name="text" >
<item row="5" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Inner corner radius</string>
</property>
</widget>
</item>
<item row="3" column="1" >
<widget class="QLineEdit" name="rinner_le" />
<item row="5" column="1">
<widget class="QLineEdit" name="rinner_le"/>
</item>
<item row="5" column="1" >
<widget class="QLineEdit" name="points_le" />
<item row="4" column="1">
<widget class="QLineEdit" name="router_le"/>
</item>
<item row="4" column="0" colspan="3" >
<widget class="Line" name="line" >
<property name="orientation" >
<item row="4" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Outer corner radius</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLineEdit" name="points_le"/>
</item>
<item row="6" column="0" colspan="3">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="0" colspan="3" >
<widget class="QLabel" name="label_4" >
<property name="text" >
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Radius to apply on polygon corners
(Radius for inner corners can be specified separately.
Leave empty to get the same radius than for outer corners)</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="3" >
<spacer name="verticalSpacer" >
<property name="orientation" >
<item row="8" column="0" colspan="3">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0" >
<property name="sizeHint" stdset="0">
<size>
<width>448</width>
<height>11</height>
@ -72,29 +80,29 @@ Leave empty to get the same radius than for outer corners)</string>
</property>
</spacer>
</item>
<item row="2" column="2" >
<widget class="QLabel" name="label_5" >
<property name="text" >
<item row="4" column="2">
<widget class="QLabel" name="label_5">
<property name="text">
<string>micron</string>
</property>
</widget>
</item>
<item row="3" column="2" >
<widget class="QLabel" name="label_6" >
<property name="text" >
<item row="5" column="2">
<widget class="QLabel" name="label_6">
<property name="text">
<string>micron</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3" >
<spacer name="verticalSpacer_2" >
<property name="orientation" >
<item row="3" column="0" colspan="3">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0" >
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
@ -102,28 +110,33 @@ Leave empty to get the same radius than for outer corners)</string>
</property>
</spacer>
</item>
<item row="7" column="0" colspan="3" >
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<item row="9" column="0" colspan="3">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
</layout>
<zorder>router_le</zorder>
<zorder>label</zorder>
<zorder>label_2</zorder>
<zorder>label_3</zorder>
<zorder>rinner_le</zorder>
<zorder>points_le</zorder>
<zorder>line</zorder>
<zorder>label_4</zorder>
<zorder>label_5</zorder>
<zorder>label_6</zorder>
<zorder>buttonBox</zorder>
</widget>
<resources/>
<connections>
@ -133,11 +146,11 @@ Leave empty to get the same radius than for outer corners)</string>
<receiver>RoundCornerOptionsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
@ -149,11 +162,11 @@ Leave empty to get the same radius than for outer corners)</string>
<receiver>RoundCornerOptionsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>

View File

@ -414,11 +414,13 @@ MakeCellOptionsDialog::button_clicked ()
// RoundCornerOptionsDialog implementation
RoundCornerOptionsDialog::RoundCornerOptionsDialog (QWidget *parent)
: QDialog (parent), mp_layout (0)
: QDialog (parent), mp_layout (0), m_router_extracted (0.0), m_rinner_extracted (0.0), m_npoints_extracted (64), m_has_extracted (false)
{
setObjectName (QString::fromUtf8 ("round_corners_options_dialog"));
Ui::RoundCornerOptionsDialog::setupUi (this);
connect (amend_cb, SIGNAL (stateChanged (int)), this, SLOT (amend_changed ()));
}
RoundCornerOptionsDialog::~RoundCornerOptionsDialog ()
@ -426,21 +428,51 @@ RoundCornerOptionsDialog::~RoundCornerOptionsDialog ()
// .. nothing yet ..
}
bool
RoundCornerOptionsDialog::exec_dialog (const db::Layout &layout, double &router, double &rinner, unsigned int &npoints)
void
RoundCornerOptionsDialog::amend_changed ()
{
if (amend_cb->isChecked () && m_has_extracted) {
router_le->setText (tl::to_qstring (tl::to_string (m_router_extracted)));
if (db::coord_traits<double>::equal (m_router_extracted, m_rinner_extracted)) {
rinner_le->setText (QString ());
} else {
rinner_le->setText (tl::to_qstring (tl::to_string (m_rinner_extracted)));
}
points_le->setText (tl::to_qstring (tl::to_string (m_npoints_extracted)));
}
}
bool
RoundCornerOptionsDialog::exec_dialog (const db::Layout &layout, double &router, double &rinner, unsigned int &npoints, bool &undo_before_apply, double router_extracted, double rinner_extracted, unsigned int npoints_extracted, bool has_extracted)
{
m_router_extracted = router_extracted;
m_rinner_extracted = rinner_extracted;
m_npoints_extracted = npoints_extracted;
m_has_extracted = has_extracted;
amend_cb->blockSignals (true);
amend_cb->setEnabled (has_extracted);
amend_cb->setChecked (undo_before_apply && has_extracted);
amend_cb->blockSignals (false);
mp_layout = &layout;
router_le->setText (tl::to_qstring (tl::to_string (router)));
if (fabs (router - rinner) < 1e-6) {
double ro = undo_before_apply && has_extracted ? router_extracted : router;
double ri = undo_before_apply && has_extracted ? rinner_extracted : rinner;
unsigned int n = undo_before_apply && has_extracted ? npoints_extracted : npoints;
router_le->setText (tl::to_qstring (tl::to_string (ro)));
if (db::coord_traits<double>::equal (ro, ri)) {
rinner_le->setText (QString ());
} else {
rinner_le->setText (tl::to_qstring (tl::to_string (rinner)));
rinner_le->setText (tl::to_qstring (tl::to_string (ri)));
}
points_le->setText (tl::to_qstring (tl::to_string (npoints)));
points_le->setText (tl::to_qstring (tl::to_string (n)));
if (QDialog::exec ()) {
undo_before_apply = m_has_extracted && amend_cb->isChecked ();
tl::from_string (tl::to_string (router_le->text ()), router);
if (rinner_le->text ().isEmpty ()) {
rinner = router;

View File

@ -173,12 +173,18 @@ public:
RoundCornerOptionsDialog (QWidget *parent);
~RoundCornerOptionsDialog ();
bool exec_dialog (const db::Layout &layout, double &rhull, double &rholes, unsigned int &npoints);
bool exec_dialog (const db::Layout &layout, double &router, double &rinner, unsigned int &npoints, bool &undo_before_apply, double router_extracted, double rinner_extracted, unsigned int npoints_extracted, bool has_extracted);
virtual void accept ();
private slots:
void amend_changed ();
private:
const db::Layout *mp_layout;
double m_router_extracted, m_rinner_extracted;
unsigned int m_npoints_extracted;
bool m_has_extracted;
};
} // namespace edt

View File

@ -60,7 +60,13 @@ MainService::MainService (db::Manager *manager, lay::LayoutView *view, lay::Plug
m_align_hmode (0), m_align_vmode (0), m_align_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_array_na (1), m_array_nb (1),
m_router (0.0), m_rinner (0.0), m_npoints (64), m_undo_before_apply (true),
mp_round_corners_dialog (0),
mp_align_options_dialog (0),
mp_flatten_inst_options_dialog (0),
mp_make_cell_options_dialog (0),
mp_make_array_options_dialog (0)
{
// .. nothing yet ..
}
@ -70,7 +76,52 @@ MainService::~MainService ()
// .. nothing yet ..
}
void
edt::RoundCornerOptionsDialog *
MainService::round_corners_dialog ()
{
if (! mp_round_corners_dialog) {
mp_round_corners_dialog = new edt::RoundCornerOptionsDialog (view ());
}
return mp_round_corners_dialog;
}
edt::AlignOptionsDialog *
MainService::align_options_dialog ()
{
if (! mp_align_options_dialog) {
mp_align_options_dialog = new edt::AlignOptionsDialog (view ());
}
return mp_align_options_dialog;
}
lay::FlattenInstOptionsDialog *
MainService::flatten_inst_options_dialog ()
{
if (! mp_flatten_inst_options_dialog) {
mp_flatten_inst_options_dialog = new lay::FlattenInstOptionsDialog (view (), false /*don't allow prunining*/);
}
return mp_flatten_inst_options_dialog;
}
edt::MakeCellOptionsDialog *
MainService::make_cell_options_dialog ()
{
if (! mp_make_cell_options_dialog) {
mp_make_cell_options_dialog = new edt::MakeCellOptionsDialog (view ());
}
return mp_make_cell_options_dialog;
}
edt::MakeArrayOptionsDialog *
MainService::make_array_options_dialog ()
{
if (! mp_make_array_options_dialog) {
mp_make_array_options_dialog = new edt::MakeArrayOptionsDialog (view ());
}
return mp_make_array_options_dialog;
}
void
MainService::menu_activated (const std::string &symbol)
{
if (symbol == "edt::descend") {
@ -318,9 +369,7 @@ MainService::cm_flatten_insts ()
tl_assert (view ()->is_editable ());
check_no_guiding_shapes ();
lay::FlattenInstOptionsDialog options_dialog (view (), false /*don't allow prunining*/);
if (options_dialog.exec_dialog (m_flatten_insts_levels, m_flatten_prune) && m_flatten_insts_levels != 0) {
if (flatten_inst_options_dialog ()->exec_dialog (m_flatten_insts_levels, m_flatten_prune) && m_flatten_insts_levels != 0) {
view ()->cancel_edits ();
@ -908,11 +957,9 @@ MainService::cm_make_cell ()
if (cv_index >= 0) {
MakeCellOptionsDialog dialog (view ());
const lay::CellView &cv = view ()->cellview (cv_index);
if (dialog.exec_dialog (cv->layout (), m_make_cell_name, m_origin_mode_x, m_origin_mode_y)) {
if (make_cell_options_dialog ()->exec_dialog (cv->layout (), m_make_cell_name, m_origin_mode_x, m_origin_mode_y)) {
// Compute the selection's bbox to establish a good origin for the new cell
db::Box selection_bbox;
@ -1231,9 +1278,10 @@ MainService::cm_convert_to_pcell ()
}
}
static void extract_rad (std::vector <db::Polygon> &poly, double &rinner, double &router, unsigned int &n)
static bool extract_rad (std::vector <db::Polygon> &poly, double &rinner, double &router, unsigned int &n)
{
std::vector <db::Point> new_pts;
bool any_extracted = false;
for (std::vector<db::Polygon>::iterator p = poly.begin (); p != poly.end (); ++p) {
@ -1246,6 +1294,7 @@ static void extract_rad (std::vector <db::Polygon> &poly, double &rinner, double
new_poly.assign_hull (p->begin_hull (), p->end_hull (), false /*don't compress*/);
} else {
new_poly.assign_hull (new_pts.begin (), new_pts.end (), true /*compress*/);
any_extracted = true;
}
for (unsigned int h = 0; h < p->holes (); ++h) {
@ -1257,13 +1306,16 @@ static void extract_rad (std::vector <db::Polygon> &poly, double &rinner, double
new_poly.insert_hole (p->begin_hole (h), p->end_hole (h), false /*don't compress*/);
} else {
new_poly.insert_hole (new_pts.begin (), new_pts.end (), true /*compress*/);
any_extracted = true;
}
}
p->swap (new_poly);
}
}
return any_extracted;
}
void
@ -1310,15 +1362,17 @@ MainService::cm_round_corners ()
// prepare: merge to remove cutlines and smooth to remove effects of cutlines
db::EdgeProcessor ep;
std::vector <db::Polygon> out;
ep.merge (primary, out, 0 /*min_wc*/, false /*resolve holes*/, true /*min coherence*/);
for (std::vector <db::Polygon>::iterator p = out.begin (); p != out.end (); ++p) {
std::vector <db::Polygon> in;
ep.merge (primary, in, 0 /*min_wc*/, false /*resolve holes*/, true /*min coherence*/);
for (std::vector <db::Polygon>::iterator p = in.begin (); p != in.end (); ++p) {
*p = smooth (*p, 1);
}
std::vector <db::Polygon> out = in;
unsigned int n = 100;
double rinner = 0.0, router = 0.0;
extract_rad (out, rinner, router, n);
bool has_extracted = extract_rad (out, rinner, router, n);
const lay::CellView &cv = view ()->cellview (cv_index);
double dbu = cv->layout ().dbu ();
@ -1326,13 +1380,16 @@ MainService::cm_round_corners ()
rinner *= dbu;
router *= dbu;
RoundCornerOptionsDialog dialog (view ());
if (! dialog.exec_dialog (cv->layout (), router, rinner, n)) {
if (! round_corners_dialog ()->exec_dialog (cv->layout (), m_router, m_rinner, m_npoints, m_undo_before_apply, router, rinner, n, has_extracted)) {
return;
}
if (! m_undo_before_apply || ! has_extracted) {
out.swap (in);
}
for (std::vector <db::Polygon>::iterator p = out.begin (); p != out.end (); ++p) {
*p = compute_rounded (*p, rinner / dbu, router / dbu, n);
*p = compute_rounded (*p, m_rinner / dbu, m_router / dbu, m_npoints);
}
// remove holes (result in primary)
@ -1700,8 +1757,7 @@ MainService::cm_align ()
std::vector<edt::Service *> edt_services = view ()->get_plugins <edt::Service> ();
AlignOptionsDialog dialog (view ());
if (! dialog.exec_dialog (view (), m_align_hmode, m_align_vmode, m_align_visible_layers)) {
if (! align_options_dialog ()->exec_dialog (view (), m_align_hmode, m_align_vmode, m_align_visible_layers)) {
return;
}
@ -1797,9 +1853,7 @@ MainService::cm_make_array ()
throw tl::Exception (tl::to_string (QObject::tr ("Nothing selected to make arrays of")));
}
MakeArrayOptionsDialog dialog (view ());
if (dialog.exec_dialog (m_array_a, m_array_na, m_array_b, m_array_nb)) {
if (make_array_options_dialog ()->exec_dialog (m_array_a, m_array_na, m_array_b, m_array_nb)) {
view ()->cancel_edits ();

View File

@ -39,6 +39,7 @@
namespace lay {
class PluginRoot;
class FlattenInstOptionsDialog;
}
namespace edt {
@ -46,6 +47,10 @@ namespace edt {
class Service;
class EditorOptionsPages;
class EditorOptionsPage;
class RoundCornerOptionsDialog;
class MakeCellOptionsDialog;
class MakeArrayOptionsDialog;
class AlignOptionsDialog;
// -------------------------------------------------------------
@ -205,9 +210,22 @@ private:
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;
edt::RoundCornerOptionsDialog *mp_round_corners_dialog;
edt::AlignOptionsDialog *mp_align_options_dialog;
lay::FlattenInstOptionsDialog *mp_flatten_inst_options_dialog;
edt::MakeCellOptionsDialog *mp_make_cell_options_dialog;
edt::MakeArrayOptionsDialog *mp_make_array_options_dialog;
void boolean_op (int mode);
void check_no_guiding_shapes ();
edt::RoundCornerOptionsDialog *round_corners_dialog ();
edt::AlignOptionsDialog *align_options_dialog ();
lay::FlattenInstOptionsDialog *flatten_inst_options_dialog ();
edt::MakeCellOptionsDialog *make_cell_options_dialog ();
edt::MakeArrayOptionsDialog *make_array_options_dialog ();
};
}