WIP: auto-measurement rulers

- More tests on the snapping functions
- Bugfixes and enhancements for ruler features
This commit is contained in:
Matthias Koefferlein 2017-07-01 23:07:33 +02:00
parent 4ebfb24fca
commit 86e2b8cad1
4 changed files with 110 additions and 33 deletions

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

View File

@ -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 ..