diff options
author | Campbell Barton <ideasman42@gmail.com> | 2016-03-29 20:56:18 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2016-03-29 21:01:57 +0300 |
commit | c3ed6010afd0a3695596125d5716d65be4b635f4 (patch) | |
tree | 0e456bcd34d28d5ba0888fc80cb4cb4334ae7fd4 /release | |
parent | 3a24e6320f31a790ea9d3c912a35db2186140b71 (diff) |
Fix T47967: Select next active fails in some cases
For cases when there are multiple matches,
find the closest match (with increasingly fuzzy tests) instead of failing.
Diffstat (limited to 'release')
-rw-r--r-- | release/scripts/startup/bl_operators/bmesh/find_adjacent.py | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/release/scripts/startup/bl_operators/bmesh/find_adjacent.py b/release/scripts/startup/bl_operators/bmesh/find_adjacent.py index 46edcd28deb..77e590fd8ce 100644 --- a/release/scripts/startup/bl_operators/bmesh/find_adjacent.py +++ b/release/scripts/startup/bl_operators/bmesh/find_adjacent.py @@ -23,6 +23,11 @@ import bmesh +__all__ = ( + "select_prev", + "select_next", + ) + def other_edges_over_face(e): # Can yield same edge multiple times, its fine. @@ -261,6 +266,52 @@ def select_next(bm, report): return False ele_pair_next = find_next(*ele_pair) + + if len(ele_pair_next) > 1: + # We have multiple options, + # check topology around the element and find the closest match + # (allow for sloppy comparison if exact checks fail). + + def ele_uuid(ele): + ele_type = type(ele) + if ele_type is bmesh.types.BMFace: + ret = [len(f.verts) for l in ele.loops for f in l.edge.link_faces if f is not ele] + elif ele_type is bmesh.types.BMEdge: + ret = [len(l.face.verts) for l in ele.link_loops] + elif ele_type is bmesh.types.BMVert: + ret = [len(l.face.verts) for l in ele.link_loops] + else: + raise TypeError("wrong type") + return tuple(sorted(ret)) + + def ele_uuid_filter(): + + def pass_fn(seq): + return seq + + def sum_set(seq): + return sum(set(seq)) + + uuid_cmp = ele_uuid(ele_pair[0]) + ele_pair_next_uuid = [(ele, ele_uuid(ele)) for ele in ele_pair_next] + + # Attempt to find the closest match, + # start specific, use increasingly more approximate comparisons. + for fn in (pass_fn, set, sum_set, len): + uuid_cmp_test = fn(uuid_cmp) + ele_pair_next_uuid_test = [ + (ele, uuid) for (ele, uuid) in ele_pair_next_uuid + if uuid_cmp_test == fn(uuid)] + if len(ele_pair_next_uuid_test) > 1: + ele_pair_next_uuid = ele_pair_next_uuid_test + elif len(ele_pair_next_uuid_test) == 1: + return [ele for (ele, uuid) in ele_pair_next_uuid_test] + return [] + + ele_pair_next[:] = ele_uuid_filter() + + del ele_uuid, ele_uuid_filter + if len(ele_pair_next) != 1: report({'INFO'}, "No single next item found") return False |