mirror of https://github.com/KLayout/klayout.git
WIP: auto-measurement rulers
- More tests on the snapping functions - Bugfixes and enhancements for ruler features
This commit is contained in:
parent
4ebfb24fca
commit
86e2b8cad1
|
|
@ -1410,9 +1410,14 @@ Service::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio
|
|||
} else if (tpl.mode () == ant::Template::RulerAutoMetric) {
|
||||
|
||||
// for auto-metric we need some cutline constraint - any or global won't do.
|
||||
lay::angle_constraint_type ac = tpl.angle_constraint ();
|
||||
ac = (ac == lay::AC_Global ? m_snap_mode : ac);
|
||||
if (ac == lay::AC_Any || ac == lay::AC_Global) {
|
||||
lay::angle_constraint_type ac = ac_from_buttons (buttons);
|
||||
if (ac == lay::AC_Global) {
|
||||
ac = tpl.angle_constraint ();
|
||||
}
|
||||
if (ac == lay::AC_Global) {
|
||||
ac = m_snap_mode;
|
||||
}
|
||||
if (ac == lay::AC_Global) {
|
||||
ac = lay::AC_Diagonal;
|
||||
}
|
||||
|
||||
|
|
@ -1424,7 +1429,7 @@ Service::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio
|
|||
double snap_range = widget ()->mouse_event_trans ().inverted ().ctrans (m_snap_range);
|
||||
snap_range *= 0.5;
|
||||
|
||||
std::pair<bool, db::DEdge> ee = lay::obj_snap2 (mp_view, p, p, g, ac, snap_range, snap_range * 1000.0);
|
||||
std::pair<bool, db::DEdge> ee = lay::obj_snap2 (mp_view, p, g, ac, snap_range, snap_range * 1000.0);
|
||||
if (ee.first) {
|
||||
|
||||
// begin the transaction
|
||||
|
|
|
|||
|
|
@ -716,8 +716,8 @@ private:
|
|||
const std::set<db::properties_id_type> *mp_prop_sel;
|
||||
bool m_inv_prop_sel;
|
||||
bool m_projection_constraint;
|
||||
bool m_directed;
|
||||
bool m_with_vertex;
|
||||
bool m_directed;
|
||||
};
|
||||
|
||||
static std::pair <bool, db::DPoint>
|
||||
|
|
@ -776,33 +776,32 @@ do_obj_snap2 (lay::LayoutView *view, const db::DPoint &pt, const db::DVector &gr
|
|||
|
||||
finder.find (view, sr);
|
||||
|
||||
if (finder.any ()) {
|
||||
if ((cutlines.empty () && finder.any ()) || finder.any_exact ()) {
|
||||
|
||||
db::DPoint p1 = finder.get_found ();
|
||||
|
||||
std::vector <db::DEdge> cl;
|
||||
db::DVector n;
|
||||
|
||||
if (finder.is_vertex () || finder.has_found_edge ()) {
|
||||
if (! cutlines.empty ()) {
|
||||
|
||||
if (finder.is_vertex ()) {
|
||||
// select those cutlines that lead to the first intersection point
|
||||
for (std::vector<db::DEdge>::const_iterator i = cutlines.begin (); i != cutlines.end (); ++i) {
|
||||
|
||||
std::pair<db::DEdge, db::DEdge> ee = finder.get_found_vertex_edges ();
|
||||
db::DVector d1 = ee.first.d ();
|
||||
if (d1.double_length () > 1e-6) {
|
||||
d1 *= (1.0 / d1.double_length ());
|
||||
}
|
||||
db::DVector d2 = ee.second.d ();
|
||||
if (d2.double_length () > 1e-6) {
|
||||
d2 *= (1.0 / d1.double_length ());
|
||||
db::DVector n = i->d ();
|
||||
db::DVector d = dp - p1;
|
||||
if (fabs (db::vprod (n, d)) < 1e-6 * n.length () * d.length ()) {
|
||||
if (db::sprod (n, d) < 0.0) {
|
||||
n = -n;
|
||||
}
|
||||
cl.push_back (db::DEdge (p1, p1 + n));
|
||||
}
|
||||
|
||||
n = ((d1 + d2) * 0.5).transformed (db::DTrans (db::DTrans::r90));
|
||||
|
||||
} else {
|
||||
n = finder.get_found_edge ().d ().transformed (db::DTrans (db::DTrans::r90));
|
||||
}
|
||||
|
||||
} else if (finder.has_found_edge ()) {
|
||||
|
||||
n = finder.get_found_edge ().d ().transformed (db::DTrans (db::DTrans::r90));
|
||||
if (db::sprod (n, dp - p1) < 0.0) {
|
||||
n = -n;
|
||||
}
|
||||
|
|
@ -874,15 +873,17 @@ obj_snap (lay::LayoutView *view, const db::DPoint &p1, const db::DPoint &p2, con
|
|||
std::pair <bool, db::DEdge>
|
||||
obj_snap2 (lay::LayoutView *view, const db::DPoint &pt, const db::DVector &grid, double min_search_range, double max_search_range)
|
||||
{
|
||||
return do_obj_snap2 (view, pt, grid, min_search_range, max_search_range, std::vector<db::DEdge> ());
|
||||
return do_obj_snap2 (view, lay::snap_xy (pt, grid), db::DVector (), min_search_range, max_search_range, std::vector<db::DEdge> ());
|
||||
}
|
||||
|
||||
std::pair <bool, db::DEdge>
|
||||
obj_snap2 (lay::LayoutView *view, const db::DPoint &p1, const db::DPoint &p2, const db::DVector &grid, lay::angle_constraint_type snap_mode, double min_search_range, double max_search_range)
|
||||
obj_snap2 (lay::LayoutView *view, const db::DPoint &pt, const db::DVector &grid, lay::angle_constraint_type snap_mode, double min_search_range, double max_search_range)
|
||||
{
|
||||
db::DPoint dp = lay::snap_xy (pt, grid);
|
||||
|
||||
std::vector <db::DEdge> cutlines;
|
||||
make_cutlines (snap_mode, p1, cutlines);
|
||||
return do_obj_snap2 (view, p2, grid, min_search_range, max_search_range, cutlines);
|
||||
make_cutlines (snap_mode, dp, cutlines);
|
||||
return do_obj_snap2 (view, dp, db::DVector (), min_search_range, max_search_range, cutlines);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,14 +127,6 @@ namespace lay
|
|||
*/
|
||||
LAYBASIC_PUBLIC std::pair <bool, db::DPoint> obj_snap (lay::LayoutView *view, const db::DPoint &pt, const db::DVector &grid, double snap_range);
|
||||
|
||||
/**
|
||||
* @brief Same than obj_snap, but delivers two points on two opposite sides of the initial point
|
||||
*
|
||||
* This method basically implements "auto measure". The first value of the returned pair
|
||||
* is true if such an edge could be found. Otherwise it's false.
|
||||
*/
|
||||
LAYBASIC_PUBLIC std::pair <bool, db::DEdge> obj_snap2 (lay::LayoutView *view, const db::DPoint &pt, const db::DVector &grid, double min_search_range, double max_search_range);
|
||||
|
||||
/**
|
||||
* @brief combined grid-, projection- and object snapping provided to implementing "magnetic features"
|
||||
*
|
||||
|
|
@ -149,7 +141,14 @@ namespace lay
|
|||
* This method basically implements "auto measure". The first value of the returned pair
|
||||
* is true if such an edge could be found. Otherwise it's false.
|
||||
*/
|
||||
LAYBASIC_PUBLIC std::pair <bool, db::DEdge> obj_snap2 (lay::LayoutView *view, const db::DPoint &pr, const db::DPoint &pt, const db::DVector &grid, lay::angle_constraint_type ac, double min_search_range, double max_search_range);
|
||||
LAYBASIC_PUBLIC std::pair <bool, db::DEdge> obj_snap2 (lay::LayoutView *view, const db::DPoint &pt, const db::DVector &grid, double min_search_range, double max_search_range);
|
||||
|
||||
/**
|
||||
* @brief Same than the previous obj_snap2, but allows specification of an angle constraint
|
||||
*
|
||||
* Measurements will be confined to the direction specified.
|
||||
*/
|
||||
LAYBASIC_PUBLIC std::pair <bool, db::DEdge> obj_snap2 (lay::LayoutView *view, const db::DPoint &pt, const db::DVector &grid, lay::angle_constraint_type ac, double min_search_range, double max_search_range);
|
||||
|
||||
/**
|
||||
* @brief Reduce a given vector according to the angle constraint
|
||||
|
|
|
|||
|
|
@ -55,10 +55,23 @@ TEST(1)
|
|||
|
||||
std::pair<bool, db::DPoint> res;
|
||||
|
||||
// not hit
|
||||
res = lay::obj_snap (&view, db::DPoint (1.505, 1.505), db::DVector (), 0.1);
|
||||
EXPECT_EQ (res.first, false);
|
||||
EXPECT_EQ (res.second.to_string (), "1.505,1.505");
|
||||
|
||||
res = lay::obj_snap (&view, db::DPoint (0.505, 0.505), db::DVector (), 0.1);
|
||||
EXPECT_EQ (res.first, true);
|
||||
EXPECT_EQ (res.second.to_string (), "0.5,0.5");
|
||||
|
||||
res = lay::obj_snap (&view, db::DPoint (0.485, 0.505), db::DVector (0.01, 0.01), 0.1);
|
||||
EXPECT_EQ (res.first, true);
|
||||
EXPECT_EQ (res.second.to_string (), "0.49,0.51");
|
||||
|
||||
res = lay::obj_snap (&view, db::DPoint (0.205, 0.215), db::DVector (0.01, 0.025), 0.1);
|
||||
EXPECT_EQ (res.first, false);
|
||||
EXPECT_EQ (res.second.to_string (), "0.21,0.225");
|
||||
|
||||
res = lay::obj_snap (&view, db::DPoint (0.505, 1.005), db::DVector (), 0.1);
|
||||
EXPECT_EQ (res.first, false);
|
||||
EXPECT_EQ (res.second.to_string (), "0.505,1.005");
|
||||
|
|
@ -71,6 +84,65 @@ TEST(1)
|
|||
EXPECT_EQ (res.first, true);
|
||||
EXPECT_EQ (res.second.to_string (), "0.495,0.505");
|
||||
|
||||
// projected snapping
|
||||
res = lay::obj_snap (&view, db::DPoint (1.000, 0.505), db::DPoint (0.005, 1.005), db::DVector (), lay::AC_Horizontal, 0.1);
|
||||
EXPECT_EQ (res.first, true);
|
||||
EXPECT_EQ (res.second.to_string (), "0,0.505");
|
||||
|
||||
std::pair<bool, db::DEdge> res2;
|
||||
|
||||
res2 = lay::obj_snap2 (&view, db::DPoint (1.5, 1.5), db::DVector (), 0.005, 1.0);
|
||||
EXPECT_EQ (res2.first, false);
|
||||
EXPECT_EQ (res2.second.to_string (), "(0,0;0,0)");
|
||||
|
||||
res2 = lay::obj_snap2 (&view, db::DPoint (0.205, 0.5), db::DVector (), 0.005, 1.0);
|
||||
EXPECT_EQ (res2.first, true);
|
||||
EXPECT_EQ (res2.second.to_string (), "(0.3525,0.6475;0,0.295)");
|
||||
|
||||
res2 = lay::obj_snap2 (&view, db::DPoint (0.205, 0.5), db::DVector (), lay::AC_Horizontal, 0.005, 1.0);
|
||||
EXPECT_EQ (res2.first, true);
|
||||
EXPECT_EQ (res2.second.to_string (), "(0,0.5;0.5,0.5)");
|
||||
|
||||
res2 = lay::obj_snap2 (&view, db::DPoint (0.205, 0.5), db::DVector (0.03, 0.03), lay::AC_Horizontal, 0.005, 1.0);
|
||||
EXPECT_EQ (res2.first, true);
|
||||
EXPECT_EQ (res2.second.to_string (), "(0,0.51;0.49,0.51)");
|
||||
|
||||
res2 = lay::obj_snap2 (&view, db::DPoint (0.205, 0.5), db::DVector (), lay::AC_Vertical, 0.005, 1.0);
|
||||
EXPECT_EQ (res2.first, true);
|
||||
EXPECT_EQ (res2.second.to_string (), "(0.205,0.795;0.205,0)");
|
||||
|
||||
res2 = lay::obj_snap2 (&view, db::DPoint (0.205, 0.5), db::DVector (), lay::AC_Diagonal, 0.005, 1.0);
|
||||
EXPECT_EQ (res2.first, true);
|
||||
EXPECT_EQ (res2.second.to_string (), "(0.3525,0.6475;0,0.295)");
|
||||
|
||||
res2 = lay::obj_snap2 (&view, db::DPoint (0.205, 0.505), db::DVector (), lay::AC_Ortho, 0.005, 1.0);
|
||||
EXPECT_EQ (res2.first, true);
|
||||
EXPECT_EQ (res2.second.to_string (), "(0,0.505;0.495,0.505)");
|
||||
|
||||
res2 = lay::obj_snap2 (&view, db::DPoint (0.205, 0.5), db::DVector (), lay::AC_Any, 0.005, 1.0);
|
||||
EXPECT_EQ (res2.first, true);
|
||||
EXPECT_EQ (res2.second.to_string (), "(0.3525,0.6475;0,0.295)");
|
||||
|
||||
res2 = lay::obj_snap2 (&view, db::DPoint (0.205, 0.495), db::DVector (0.01, 0.01), 0.005, 1.0);
|
||||
EXPECT_EQ (res2.first, true);
|
||||
EXPECT_EQ (res2.second.to_string (), "(0.355,0.645;0,0.29)");
|
||||
|
||||
res2 = lay::obj_snap2 (&view, db::DPoint (0.5, 0.5), db::DVector (), 0.005, 1.0);
|
||||
EXPECT_EQ (res2.first, false);
|
||||
EXPECT_EQ (res2.second.to_string (), "(0,0;0,0)");
|
||||
|
||||
res2 = lay::obj_snap2 (&view, db::DPoint (0.005, 0.5), db::DVector (), 0.005, 1.0);
|
||||
EXPECT_EQ (res2.first, true);
|
||||
EXPECT_EQ (res2.second.to_string (), "(0,0.5;0.5,0.5)");
|
||||
|
||||
res2 = lay::obj_snap2 (&view, db::DPoint (0.0, 0.5), db::DVector (), 0.005, 1.0);
|
||||
EXPECT_EQ (res2.first, false);
|
||||
EXPECT_EQ (res2.second.to_string (), "(0,0;0,0)");
|
||||
|
||||
res2 = lay::obj_snap2 (&view, db::DPoint (-0.2, 0.5), db::DVector (), 0.005, 1.0);
|
||||
EXPECT_EQ (res2.first, false);
|
||||
EXPECT_EQ (res2.second.to_string (), "(0,0;0,0)");
|
||||
|
||||
}
|
||||
|
||||
// .. TODO: implement ..
|
||||
|
|
|
|||
Loading…
Reference in New Issue