diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-01-04 11:57:33 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-01-04 11:57:33 +0400 |
commit | ab913fe15de957faf38aac11635d68e83df457f4 (patch) | |
tree | 5a96cf9a84b4bbfd90ec8f28263c91f0e5ca40e9 /release | |
parent | 6fabbcb4dde782448df2079d6dba625720d9b487 (diff) |
add length average option to 'Follow Active Quads' unwrap, gives nicer results.
Diffstat (limited to 'release')
-rw-r--r-- | release/scripts/startup/bl_operators/uvcalc_follow_active.py | 79 |
1 files changed, 71 insertions, 8 deletions
diff --git a/release/scripts/startup/bl_operators/uvcalc_follow_active.py b/release/scripts/startup/bl_operators/uvcalc_follow_active.py index 727c4ad739f..d870ef963ea 100644 --- a/release/scripts/startup/bl_operators/uvcalc_follow_active.py +++ b/release/scripts/startup/bl_operators/uvcalc_follow_active.py @@ -26,6 +26,7 @@ from bpy.types import Operator def extend(obj, operator, EXTEND_MODE): + import bmesh me = obj.data # script will fail without UVs @@ -46,12 +47,12 @@ def extend(obj, operator, EXTEND_MODE): faces = [f for f in bm.faces if f.select and len(f.verts) == 4] - for f in faces: - f.tag = False - f_act.tag = True - - # our own local walker + def walk_face_init(faces, f_act): + for f in faces: + f.tag = False + f_act.tag = True + def walk_face(f): # all faces in this list must be tagged f.tag = True @@ -73,6 +74,30 @@ def extend(obj, operator, EXTEND_MODE): faces_a, faces_b = faces_b, faces_a faces_b.clear() + def walk_edgeloop(l): + """ + Could make this a generic function + """ + e_first = l.edge + e = None + while True: + e = l.edge + yield e + + # don't step past non-manifold edges + if e.is_manifold: + # welk around the quad and then onto the next face + l = l.link_loop_radial_next + if len(l.face.verts) == 4: + l = l.link_loop_next.link_loop_next + if l.edge is e_first: + break + else: + break + else: + break + + def extrapolate_uv(fac, l_a_outer, l_a_inner, l_b_outer, l_b_inner): @@ -119,7 +144,9 @@ def extend(obj, operator, EXTEND_MODE): l_a_uv = [l[uv_act].uv for l in l_a] l_b_uv = [l[uv_act].uv for l in l_b] - if EXTEND_MODE == 'LENGTH': + if EXTEND_MODE == 'LENGTH_AVERAGE': + fac = edge_lengths[l_b[2].edge.index][0] / edge_lengths[l_a[1].edge.index][0] + elif EXTEND_MODE == 'LENGTH': a0, b0, c0 = l_a[3].vert.co, l_a[0].vert.co, l_b[3].vert.co a1, b1, c1 = l_a[2].vert.co, l_a[1].vert.co, l_b[2].vert.co @@ -140,6 +167,40 @@ def extend(obj, operator, EXTEND_MODE): l_a_uv[2], l_a_uv[1], l_b_uv[2], l_b_uv[1]) + # ------------------------------------------- + # Calculate average length per loop if needed + + if EXTEND_MODE == 'LENGTH_AVERAGE': + bm.edges.index_update() + edge_lengths = [None] * len(bm.edges) + + for f in faces: + # we know its a quad + l_quad = f.loops[:] + l_pair_a = (l_quad[0], l_quad[2]) + l_pair_b = (l_quad[1], l_quad[3]) + + for l_pair in (l_pair_a, l_pair_b): + if edge_lengths[l_pair[0].edge.index] is None: + + edge_length_store = [-1.0] + edge_length_accum = 0.0 + edge_length_total = 0 + + for l in l_pair: + if edge_lengths[l.edge.index] is None: + for e in walk_edgeloop(l): + if edge_lengths[e.index] is None: + edge_lengths[e.index] = edge_length_store + edge_length_accum += e.calc_length() + edge_length_total += 1 + + edge_length_store[0] = edge_length_accum / edge_length_total + + # done with average length + # ------------------------ + + walk_face_init(faces, f_act) for f_triple in walk_face(f_act): apply_uv(*f_triple) @@ -162,8 +223,10 @@ class FollowActiveQuads(Operator): name="Edge Length Mode", description="Method to space UV edge loops", items=(('EVEN', "Even", "Space all UVs evenly"), - ('LENGTH', "Length", "Average space UVs edge length of each loop")), - default='LENGTH', + ('LENGTH', "Length", "Average space UVs edge length of each loop"), + ('LENGTH_AVERAGE', "Length Average", "Average space UVs edge length of each loop"), + ), + default='LENGTH_AVERAGE', ) @classmethod |