mirror of https://github.com/KLayout/klayout.git
WIP: computation of via size, bug fixes
This commit is contained in:
parent
3df715f078
commit
d77eb32db4
|
|
@ -113,6 +113,12 @@ ShapeEditService::get_edit_layer ()
|
|||
{
|
||||
lay::LayerPropertiesConstIterator cl = view ()->current_layer ();
|
||||
|
||||
if (cl.is_null ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Please select a layer first")));
|
||||
} else if (! cl->valid (true)) {
|
||||
throw tl::Exception (tl::to_string (tr ("The selected layer is not valid")));
|
||||
}
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
if (! cl->visible (true)) {
|
||||
lay::TipDialog td (QApplication::activeWindow (),
|
||||
|
|
@ -122,12 +128,6 @@ ShapeEditService::get_edit_layer ()
|
|||
}
|
||||
#endif
|
||||
|
||||
if (cl.is_null ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Please select a layer first")));
|
||||
} else if (! cl->valid (true)) {
|
||||
throw tl::Exception (tl::to_string (tr ("The selected layer is not valid")));
|
||||
}
|
||||
|
||||
int cv_index = cl->cellview_index ();
|
||||
const lay::CellView &cv = view ()->cellview (cv_index);
|
||||
|
||||
|
|
@ -1651,6 +1651,95 @@ PathService::via_initial (int dir)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
PathService::compute_via_wh (double &w, double &h, const db::DVector &dwire, double var_ext)
|
||||
{
|
||||
w = 0.0, h = 0.0;
|
||||
|
||||
if (m_type == Round) {
|
||||
|
||||
// a square sitting in the circle at the end
|
||||
w = h = sqrt (0.5) * m_width;
|
||||
|
||||
} else {
|
||||
|
||||
double ext = 0.0;
|
||||
if (m_type == Square) {
|
||||
ext = m_width * 0.5;
|
||||
} else if (m_type == Variable) {
|
||||
ext = var_ext;
|
||||
}
|
||||
|
||||
double vl = dwire.length ();
|
||||
|
||||
if (vl < db::epsilon || ext < -db::epsilon) {
|
||||
|
||||
// no specific dimension
|
||||
|
||||
} else if (ext < db::epsilon) {
|
||||
|
||||
// a rectangle enclosing the flush end edge
|
||||
db::DVector l = dwire * (m_width / vl);
|
||||
w = std::abs (l.y ());
|
||||
h = std::abs (l.x ());
|
||||
|
||||
} else if (std::fabs (dwire.x ()) < db::epsilon) {
|
||||
|
||||
// vertical path
|
||||
w = m_width;
|
||||
h = ext * 2.0;
|
||||
|
||||
} else if (std::fabs (dwire.y ()) < db::epsilon) {
|
||||
|
||||
// horizontal path
|
||||
h = m_width;
|
||||
w = ext * 2.0;
|
||||
|
||||
} else {
|
||||
|
||||
// compute dimension of max. inscribed box
|
||||
|
||||
db::DVector v = db::DVector (std::abs (dwire.x ()) / vl, std::abs (dwire.y ()) / vl);
|
||||
|
||||
double e = ext, en = m_width * 0.5;
|
||||
|
||||
bool swap_xy = false;
|
||||
if (e > en) {
|
||||
std::swap (e, en);
|
||||
v = db::DVector (v.y (), v.x ());
|
||||
swap_xy = true;
|
||||
}
|
||||
|
||||
double vd = v.y () * v.y () - v.x () * v.x ();
|
||||
double vp = v.x () * v.y ();
|
||||
|
||||
double l = e * 0.5 * vd / vp;
|
||||
|
||||
if (std::abs (vd) > db::epsilon) {
|
||||
double l1 = (en - 2 * e * vp) / vd;
|
||||
double l2 = (-en - 2 * e * vp) / vd;
|
||||
l = std::max (l, std::min (l1, l2));
|
||||
l = std::min (l, std::max (l1, l2));
|
||||
}
|
||||
|
||||
db::DVector a = v * e + db::DVector (v.y (), -v.x ()) * l;
|
||||
w = a.x () * 2.0;
|
||||
h = a.y () * 2.0;
|
||||
|
||||
if (swap_xy) {
|
||||
std::swap (w, h);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// round down to DBU @@@ (grid)
|
||||
double dbu = layout ().dbu ();
|
||||
w = floor (w / dbu + db::epsilon) * dbu;
|
||||
h = floor (h / dbu + db::epsilon) * dbu;
|
||||
}
|
||||
|
||||
void
|
||||
PathService::via_editing (int dir)
|
||||
{
|
||||
|
|
@ -1673,14 +1762,14 @@ PathService::via_editing (int dir)
|
|||
|
||||
// compute the via parameters
|
||||
|
||||
double w_bottom = 0.0, h_bottom = 0.0, w_top = 0.0, h_top = 0.0;
|
||||
db::DVector dwire = m_points.back () - m_points [m_points.size () - 2];
|
||||
if (std::abs (dwire.y ()) > db::epsilon) {
|
||||
(is_bottom ? w_bottom : w_top) = m_width;
|
||||
}
|
||||
if (std::abs (dwire.x ()) > db::epsilon) {
|
||||
(is_bottom ? h_bottom : h_top) = m_width;
|
||||
}
|
||||
|
||||
double w = 0.0, h = 0.0;
|
||||
compute_via_wh (w, h, dwire, m_endext);
|
||||
|
||||
double w_bottom = 0.0, h_bottom = 0.0, w_top = 0.0, h_top = 0.0;
|
||||
(is_bottom ? w_bottom : w_top) = w;
|
||||
(is_bottom ? h_bottom : h_top) = h;
|
||||
|
||||
// create the path and via
|
||||
|
||||
|
|
@ -1731,13 +1820,7 @@ PathService::update_via ()
|
|||
bool is_bottom = ps.via_type.bottom.log_equal (lp);
|
||||
|
||||
double w = 0.0, h = 0.0;
|
||||
db::DVector dwire = m_points [1] - m_points.front ();
|
||||
if (std::abs (dwire.y ()) > db::epsilon) {
|
||||
w = m_width;
|
||||
}
|
||||
if (std::abs (dwire.x ()) > db::epsilon) {
|
||||
h = m_width;
|
||||
}
|
||||
compute_via_wh (w, h, m_points [1] - m_points [0], m_bgnext);
|
||||
|
||||
std::map<std::string, tl::Variant> params;
|
||||
|
||||
|
|
|
|||
|
|
@ -275,6 +275,7 @@ private:
|
|||
db::Path get_path () const;
|
||||
void set_last_point (const db::DPoint &p);
|
||||
void update_via ();
|
||||
void compute_via_wh (double &w, double &h, const db::DVector &dwire, double var_ext);
|
||||
db::Instance make_via (const db::SelectedViaDefinition &via_def, double w_bottom, double h_bottom, double w_top, double h_top, const db::DPoint &via_pos);
|
||||
void via_initial (int dir);
|
||||
void via_editing (int dir);
|
||||
|
|
|
|||
Loading…
Reference in New Issue