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 ();
|
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 defined(HAVE_QT)
|
||||||
if (! cl->visible (true)) {
|
if (! cl->visible (true)) {
|
||||||
lay::TipDialog td (QApplication::activeWindow (),
|
lay::TipDialog td (QApplication::activeWindow (),
|
||||||
|
|
@ -122,12 +128,6 @@ ShapeEditService::get_edit_layer ()
|
||||||
}
|
}
|
||||||
#endif
|
#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 ();
|
int cv_index = cl->cellview_index ();
|
||||||
const lay::CellView &cv = view ()->cellview (cv_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
|
void
|
||||||
PathService::via_editing (int dir)
|
PathService::via_editing (int dir)
|
||||||
{
|
{
|
||||||
|
|
@ -1673,14 +1762,14 @@ PathService::via_editing (int dir)
|
||||||
|
|
||||||
// compute the via parameters
|
// 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];
|
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;
|
double w = 0.0, h = 0.0;
|
||||||
}
|
compute_via_wh (w, h, dwire, m_endext);
|
||||||
if (std::abs (dwire.x ()) > db::epsilon) {
|
|
||||||
(is_bottom ? h_bottom : h_top) = m_width;
|
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
|
// create the path and via
|
||||||
|
|
||||||
|
|
@ -1731,13 +1820,7 @@ PathService::update_via ()
|
||||||
bool is_bottom = ps.via_type.bottom.log_equal (lp);
|
bool is_bottom = ps.via_type.bottom.log_equal (lp);
|
||||||
|
|
||||||
double w = 0.0, h = 0.0;
|
double w = 0.0, h = 0.0;
|
||||||
db::DVector dwire = m_points [1] - m_points.front ();
|
compute_via_wh (w, h, m_points [1] - m_points [0], m_bgnext);
|
||||||
if (std::abs (dwire.y ()) > db::epsilon) {
|
|
||||||
w = m_width;
|
|
||||||
}
|
|
||||||
if (std::abs (dwire.x ()) > db::epsilon) {
|
|
||||||
h = m_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<std::string, tl::Variant> params;
|
std::map<std::string, tl::Variant> params;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -275,6 +275,7 @@ private:
|
||||||
db::Path get_path () const;
|
db::Path get_path () const;
|
||||||
void set_last_point (const db::DPoint &p);
|
void set_last_point (const db::DPoint &p);
|
||||||
void update_via ();
|
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);
|
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_initial (int dir);
|
||||||
void via_editing (int dir);
|
void via_editing (int dir);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue