diff options
Diffstat (limited to 'uv_magic_uv/legacy/op/align_uv.py')
-rw-r--r-- | uv_magic_uv/legacy/op/align_uv.py | 791 |
1 files changed, 17 insertions, 774 deletions
diff --git a/uv_magic_uv/legacy/op/align_uv.py b/uv_magic_uv/legacy/op/align_uv.py index 9d0ff5f4..a274d583 100644 --- a/uv_magic_uv/legacy/op/align_uv.py +++ b/uv_magic_uv/legacy/op/align_uv.py @@ -23,52 +23,16 @@ __status__ = "production" __version__ = "5.2" __date__ = "17 Nov 2018" -import math -from math import atan2, tan, sin, cos - import bpy -import bmesh -from mathutils import Vector from bpy.props import EnumProperty, BoolProperty, FloatProperty -from ... import common from ...utils.bl_class_registry import BlClassRegistry from ...utils.property_class_registry import PropertyClassRegistry - - -__all__ = [ - 'Properties', - 'MUV_OT_AlignUV_Circle', - 'MUV_OT_AlignUV_Straighten', - 'MUV_OT_AlignUV_Axis', -] - - -def is_valid_context(context): - obj = context.object - - # only edit mode is allowed to execute - if obj is None: - return False - if obj.type != 'MESH': - return False - if context.object.mode != 'EDIT': - return False - - # 'IMAGE_EDITOR' and 'VIEW_3D' space is allowed to execute. - # If 'View_3D' space is not allowed, you can't find option in Tool-Shelf - # after the execution - for space in context.area.spaces: - if (space.type == 'IMAGE_EDITOR') or (space.type == 'VIEW_3D'): - break - else: - return False - - return True +from ...impl import align_uv_impl as impl @PropertyClassRegistry(legacy=True) -class Properties: +class _Properties: idname = "align_uv" @classmethod @@ -129,58 +93,6 @@ class Properties: del scene.muv_align_uv_location -# get sum vertex length of loop sequences -def get_loop_vert_len(loops): - length = 0 - for l1, l2 in zip(loops[:-1], loops[1:]): - diff = l2.vert.co - l1.vert.co - length = length + abs(diff.length) - - return length - - -# get sum uv length of loop sequences -def get_loop_uv_len(loops, uv_layer): - length = 0 - for l1, l2 in zip(loops[:-1], loops[1:]): - diff = l2[uv_layer].uv - l1[uv_layer].uv - length = length + abs(diff.length) - - return length - - -# get center/radius of circle by 3 vertices -def get_circle(v): - alpha = atan2((v[0].y - v[1].y), (v[0].x - v[1].x)) + math.pi / 2 - beta = atan2((v[1].y - v[2].y), (v[1].x - v[2].x)) + math.pi / 2 - ex = (v[0].x + v[1].x) / 2.0 - ey = (v[0].y + v[1].y) / 2.0 - fx = (v[1].x + v[2].x) / 2.0 - fy = (v[1].y + v[2].y) / 2.0 - cx = (ey - fy - ex * tan(alpha) + fx * tan(beta)) / \ - (tan(beta) - tan(alpha)) - cy = ey - (ex - cx) * tan(alpha) - center = Vector((cx, cy)) - - r = v[0] - center - radian = r.length - - return center, radian - - -# get position on circle with same arc length -def calc_v_on_circle(v, center, radius): - base = v[0] - theta = atan2(base.y - center.y, base.x - center.x) - new_v = [] - for i in range(len(v)): - angle = theta + i * 2 * math.pi / len(v) - new_v.append(Vector((center.x + radius * sin(angle), - center.y + radius * cos(angle)))) - - return new_v - - @BlClassRegistry(legacy=True) class MUV_OT_AlignUV_Circle(bpy.types.Operator): @@ -200,247 +112,15 @@ class MUV_OT_AlignUV_Circle(bpy.types.Operator): default=False ) + def __init__(self): + self.__impl = impl.CircleImpl() + @classmethod def poll(cls, context): - # we can not get area/space/region from console - if common.is_console_mode(): - return True - return is_valid_context(context) + return impl.CircleImpl.poll(context) def execute(self, context): - obj = context.active_object - bm = bmesh.from_edit_mesh(obj.data) - if common.check_version(2, 73, 0) >= 0: - bm.faces.ensure_lookup_table() - uv_layer = bm.loops.layers.uv.verify() - - # loop_seqs[horizontal][vertical][loop] - loop_seqs, error = common.get_loop_sequences(bm, uv_layer, True) - if not loop_seqs: - self.report({'WARNING'}, error) - return {'CANCELLED'} - - # get circle and new UVs - uvs = [hseq[0][0][uv_layer].uv.copy() for hseq in loop_seqs] - c, r = get_circle(uvs[0:3]) - new_uvs = calc_v_on_circle(uvs, c, r) - - # check center UV of circle - center = loop_seqs[0][-1][0].vert - for hseq in loop_seqs[1:]: - if len(hseq[-1]) != 1: - self.report({'WARNING'}, "Last face must be triangle") - return {'CANCELLED'} - if hseq[-1][0].vert != center: - self.report({'WARNING'}, "Center must be identical") - return {'CANCELLED'} - - # align to circle - if self.transmission: - for hidx, hseq in enumerate(loop_seqs): - for vidx, pair in enumerate(hseq): - all_ = int((len(hseq) + 1) / 2) - r = (all_ - int((vidx + 1) / 2)) / all_ - pair[0][uv_layer].uv = c + (new_uvs[hidx] - c) * r - if self.select: - pair[0][uv_layer].select = True - - if len(pair) < 2: - continue - # for quad polygon - next_hidx = (hidx + 1) % len(loop_seqs) - pair[1][uv_layer].uv = c + ((new_uvs[next_hidx]) - c) * r - if self.select: - pair[1][uv_layer].select = True - else: - for hidx, hseq in enumerate(loop_seqs): - pair = hseq[0] - pair[0][uv_layer].uv = new_uvs[hidx] - pair[1][uv_layer].uv = new_uvs[(hidx + 1) % len(loop_seqs)] - if self.select: - pair[0][uv_layer].select = True - pair[1][uv_layer].select = True - - bmesh.update_edit_mesh(obj.data) - - return {'FINISHED'} - - -# get accumulate vertex lengths of loop sequences -def get_loop_vert_accum_len(loops): - accum_lengths = [0.0] - length = 0 - for l1, l2 in zip(loops[:-1], loops[1:]): - diff = l2.vert.co - l1.vert.co - length = length + abs(diff.length) - accum_lengths.extend([length]) - - return accum_lengths - - -# get sum uv length of loop sequences -def get_loop_uv_accum_len(loops, uv_layer): - accum_lengths = [0.0] - length = 0 - for l1, l2 in zip(loops[:-1], loops[1:]): - diff = l2[uv_layer].uv - l1[uv_layer].uv - length = length + abs(diff.length) - accum_lengths.extend([length]) - - return accum_lengths - - -# get horizontal differential of UV influenced by mesh vertex -def get_hdiff_uv_vinfl(uv_layer, loop_seqs, vidx, hidx, pidx, infl): - common.debug_print( - "loop_seqs[hidx={0}][vidx={1}][pidx={2}]".format(hidx, vidx, pidx)) - - base_uv = loop_seqs[0][vidx][0][uv_layer].uv.copy() - - # calculate original length - hloops = [] - for s in loop_seqs: - hloops.extend([s[vidx][0], s[vidx][1]]) - total_vlen = get_loop_vert_len(hloops) - accum_vlens = get_loop_vert_accum_len(hloops) - total_uvlen = get_loop_uv_len(hloops, uv_layer) - accum_uvlens = get_loop_uv_accum_len(hloops, uv_layer) - orig_uvs = [l[uv_layer].uv.copy() for l in hloops] - - # calculate target length - tgt_noinfl = total_uvlen * (hidx + pidx) / len(loop_seqs) - tgt_infl = total_uvlen * accum_vlens[hidx * 2 + pidx] / total_vlen - target_length = tgt_noinfl * (1 - infl) + tgt_infl * infl - common.debug_print(target_length) - common.debug_print(accum_uvlens) - - # calculate target UV - for i in range(len(accum_uvlens[:-1])): - # get line segment which UV will be placed - if ((accum_uvlens[i] <= target_length) and - (accum_uvlens[i + 1] > target_length)): - tgt_seg_len = target_length - accum_uvlens[i] - seg_len = accum_uvlens[i + 1] - accum_uvlens[i] - uv1 = orig_uvs[i] - uv2 = orig_uvs[i + 1] - target_uv = (uv1 - base_uv) + (uv2 - uv1) * tgt_seg_len / seg_len - break - elif i == (len(accum_uvlens[:-1]) - 1): - if accum_uvlens[i + 1] != target_length: - raise Exception( - "Internal Error: horizontal_target_length={}" - " is not equal to {}" - .format(target_length, accum_uvlens[-1])) - tgt_seg_len = target_length - accum_uvlens[i] - seg_len = accum_uvlens[i + 1] - accum_uvlens[i] - uv1 = orig_uvs[i] - uv2 = orig_uvs[i + 1] - target_uv = (uv1 - base_uv) + (uv2 - uv1) * tgt_seg_len / seg_len - break - else: - raise Exception("Internal Error: horizontal_target_length={}" - " is not in range {} to {}" - .format(target_length, accum_uvlens[0], - accum_uvlens[-1])) - - return target_uv - - -# --------------------- LOOP STRUCTURE ---------------------- -# -# loops[hidx][vidx][pidx] -# hidx: horizontal index -# vidx: vertical index -# pidx: pair index -# -# <----- horizontal -----> -# -# (hidx, vidx, pidx) = (0, 3, 0) -# | (hidx, vidx, pidx) = (1, 3, 0) -# v v -# ^ o --- oo --- o -# | | || | -# vertical | o --- oo --- o <- (hidx, vidx, pidx) -# | o --- oo --- o = (1, 2, 1) -# | | || | -# v o --- oo --- o -# ^ ^ -# | (hidx, vidx, pidx) = (1, 0, 1) -# (hidx, vidx, pidx) = (0, 0, 0) -# -# ----------------------------------------------------------- - - -# get vertical differential of UV influenced by mesh vertex -def get_vdiff_uv_vinfl(uv_layer, loop_seqs, vidx, hidx, pidx, infl): - common.debug_print( - "loop_seqs[hidx={0}][vidx={1}][pidx={2}]".format(hidx, vidx, pidx)) - - base_uv = loop_seqs[hidx][0][pidx][uv_layer].uv.copy() - - # calculate original length - vloops = [] - for s in loop_seqs[hidx]: - vloops.append(s[pidx]) - total_vlen = get_loop_vert_len(vloops) - accum_vlens = get_loop_vert_accum_len(vloops) - total_uvlen = get_loop_uv_len(vloops, uv_layer) - accum_uvlens = get_loop_uv_accum_len(vloops, uv_layer) - orig_uvs = [l[uv_layer].uv.copy() for l in vloops] - - # calculate target length - tgt_noinfl = total_uvlen * int((vidx + 1) / 2) / len(loop_seqs) - tgt_infl = total_uvlen * accum_vlens[vidx] / total_vlen - target_length = tgt_noinfl * (1 - infl) + tgt_infl * infl - common.debug_print(target_length) - common.debug_print(accum_uvlens) - - # calculate target UV - for i in range(len(accum_uvlens[:-1])): - # get line segment which UV will be placed - if ((accum_uvlens[i] <= target_length) and - (accum_uvlens[i + 1] > target_length)): - tgt_seg_len = target_length - accum_uvlens[i] - seg_len = accum_uvlens[i + 1] - accum_uvlens[i] - uv1 = orig_uvs[i] - uv2 = orig_uvs[i + 1] - target_uv = (uv1 - base_uv) + (uv2 - uv1) * tgt_seg_len / seg_len - break - elif i == (len(accum_uvlens[:-1]) - 1): - if accum_uvlens[i + 1] != target_length: - raise Exception("Internal Error: horizontal_target_length={}" - " is not equal to {}" - .format(target_length, accum_uvlens[-1])) - tgt_seg_len = target_length - accum_uvlens[i] - seg_len = accum_uvlens[i + 1] - accum_uvlens[i] - uv1 = orig_uvs[i] - uv2 = orig_uvs[i + 1] - target_uv = (uv1 - base_uv) + (uv2 - uv1) * tgt_seg_len / seg_len - break - else: - raise Exception("Internal Error: horizontal_target_length={}" - " is not in range {} to {}" - .format(target_length, accum_uvlens[0], - accum_uvlens[-1])) - - return target_uv - - -# get horizontal differential of UV no influenced -def get_hdiff_uv(uv_layer, loop_seqs, hidx): - base_uv = loop_seqs[0][0][0][uv_layer].uv.copy() - h_uv = loop_seqs[-1][0][1][uv_layer].uv.copy() - base_uv - - return hidx * h_uv / len(loop_seqs) - - -# get vertical differential of UV no influenced -def get_vdiff_uv(uv_layer, loop_seqs, vidx, hidx): - base_uv = loop_seqs[0][0][0][uv_layer].uv.copy() - v_uv = loop_seqs[0][-1][0][uv_layer].uv.copy() - base_uv - - hseq = loop_seqs[hidx] - return int((vidx + 1) / 2) * v_uv / (len(hseq) / 2) + return self.__impl.execute(self, context) @BlClassRegistry(legacy=True) @@ -481,117 +161,15 @@ class MUV_OT_AlignUV_Straighten(bpy.types.Operator): default=0.0 ) + def __init__(self): + self.__impl = impl.StraightenImpl() + @classmethod def poll(cls, context): - # we can not get area/space/region from console - if common.is_console_mode(): - return True - return is_valid_context(context) - - # selected and paralleled UV loop sequence will be aligned - def __align_w_transmission(self, loop_seqs, uv_layer): - base_uv = loop_seqs[0][0][0][uv_layer].uv.copy() - - # calculate diff UVs - diff_uvs = [] - # hseq[vertical][loop] - for hidx, hseq in enumerate(loop_seqs): - # pair[loop] - diffs = [] - for vidx in range(0, len(hseq), 2): - if self.horizontal: - hdiff_uvs = [ - get_hdiff_uv_vinfl(uv_layer, loop_seqs, vidx, hidx, 0, - self.mesh_infl), - get_hdiff_uv_vinfl(uv_layer, loop_seqs, vidx, hidx, 1, - self.mesh_infl), - get_hdiff_uv_vinfl(uv_layer, loop_seqs, vidx + 1, - hidx, 0, self.mesh_infl), - get_hdiff_uv_vinfl(uv_layer, loop_seqs, vidx + 1, - hidx, 1, self.mesh_infl), - ] - else: - hdiff_uvs = [ - get_hdiff_uv(uv_layer, loop_seqs, hidx), - get_hdiff_uv(uv_layer, loop_seqs, hidx + 1), - get_hdiff_uv(uv_layer, loop_seqs, hidx), - get_hdiff_uv(uv_layer, loop_seqs, hidx + 1) - ] - if self.vertical: - vdiff_uvs = [ - get_vdiff_uv_vinfl(uv_layer, loop_seqs, vidx, hidx, 0, - self.mesh_infl), - get_vdiff_uv_vinfl(uv_layer, loop_seqs, vidx, hidx, 1, - self.mesh_infl), - get_vdiff_uv_vinfl(uv_layer, loop_seqs, vidx + 1, - hidx, 0, self.mesh_infl), - get_vdiff_uv_vinfl(uv_layer, loop_seqs, vidx + 1, - hidx, 1, self.mesh_infl), - ] - else: - vdiff_uvs = [ - get_vdiff_uv(uv_layer, loop_seqs, vidx, hidx), - get_vdiff_uv(uv_layer, loop_seqs, vidx, hidx), - get_vdiff_uv(uv_layer, loop_seqs, vidx + 1, hidx), - get_vdiff_uv(uv_layer, loop_seqs, vidx + 1, hidx) - ] - diffs.append([hdiff_uvs, vdiff_uvs]) - diff_uvs.append(diffs) - - # update UV - for hseq, diffs in zip(loop_seqs, diff_uvs): - for vidx in range(0, len(hseq), 2): - loops = [ - hseq[vidx][0], hseq[vidx][1], - hseq[vidx + 1][0], hseq[vidx + 1][1] - ] - for l, hdiff, vdiff in zip(loops, diffs[int(vidx / 2)][0], - diffs[int(vidx / 2)][1]): - l[uv_layer].uv = base_uv + hdiff + vdiff - if self.select: - l[uv_layer].select = True - - # only selected UV loop sequence will be aligned - def __align_wo_transmission(self, loop_seqs, uv_layer): - base_uv = loop_seqs[0][0][0][uv_layer].uv.copy() - - h_uv = loop_seqs[-1][0][1][uv_layer].uv.copy() - base_uv - for hidx, hseq in enumerate(loop_seqs): - # only selected loop pair is targeted - pair = hseq[0] - hdiff_uv_0 = hidx * h_uv / len(loop_seqs) - hdiff_uv_1 = (hidx + 1) * h_uv / len(loop_seqs) - pair[0][uv_layer].uv = base_uv + hdiff_uv_0 - pair[1][uv_layer].uv = base_uv + hdiff_uv_1 - if self.select: - pair[0][uv_layer].select = True - pair[1][uv_layer].select = True - - def __align(self, loop_seqs, uv_layer): - if self.transmission: - self.__align_w_transmission(loop_seqs, uv_layer) - else: - self.__align_wo_transmission(loop_seqs, uv_layer) + return impl.StraightenImpl.poll(context) def execute(self, context): - obj = context.active_object - bm = bmesh.from_edit_mesh(obj.data) - if common.check_version(2, 73, 0) >= 0: - bm.faces.ensure_lookup_table() - uv_layer = bm.loops.layers.uv.verify() - - # loop_seqs[horizontal][vertical][loop] - loop_seqs, error = common.get_loop_sequences(bm, uv_layer) - if not loop_seqs: - self.report({'WARNING'}, error) - return {'CANCELLED'} - - # align - self.__align(loop_seqs, uv_layer) - - bmesh.update_edit_mesh(obj.data) - - return {'FINISHED'} + return self.__impl.execute(self, context) @BlClassRegistry(legacy=True) @@ -642,347 +220,12 @@ class MUV_OT_AlignUV_Axis(bpy.types.Operator): default=0.0 ) + def __init__(self): + self.__impl = impl.AxisImpl() + @classmethod def poll(cls, context): - # we can not get area/space/region from console - if common.is_console_mode(): - return True - return is_valid_context(context) - - # get min/max of UV - def __get_uv_max_min(self, loop_seqs, uv_layer): - uv_max = Vector((-1000000.0, -1000000.0)) - uv_min = Vector((1000000.0, 1000000.0)) - for hseq in loop_seqs: - for l in hseq[0]: - uv = l[uv_layer].uv - uv_max.x = max(uv.x, uv_max.x) - uv_max.y = max(uv.y, uv_max.y) - uv_min.x = min(uv.x, uv_min.x) - uv_min.y = min(uv.y, uv_min.y) - - return uv_max, uv_min - - # get UV differentiation when UVs are aligned to X-axis - def __get_x_axis_align_diff_uvs(self, loop_seqs, uv_layer, uv_min, - width, height): - diff_uvs = [] - for hidx, hseq in enumerate(loop_seqs): - pair = hseq[0] - luv0 = pair[0][uv_layer] - luv1 = pair[1][uv_layer] - target_uv0 = Vector((0.0, 0.0)) - target_uv1 = Vector((0.0, 0.0)) - if self.location == 'RIGHT_BOTTOM': - target_uv0.y = target_uv1.y = uv_min.y - elif self.location == 'MIDDLE': - target_uv0.y = target_uv1.y = uv_min.y + height * 0.5 - elif self.location == 'LEFT_TOP': - target_uv0.y = target_uv1.y = uv_min.y + height - if luv0.uv.x < luv1.uv.x: - target_uv0.x = uv_min.x + hidx * width / len(loop_seqs) - target_uv1.x = uv_min.x + (hidx + 1) * width / len(loop_seqs) - else: - target_uv0.x = uv_min.x + (hidx + 1) * width / len(loop_seqs) - target_uv1.x = uv_min.x + hidx * width / len(loop_seqs) - diff_uvs.append([target_uv0 - luv0.uv, target_uv1 - luv1.uv]) - - return diff_uvs - - # get UV differentiation when UVs are aligned to Y-axis - def __get_y_axis_align_diff_uvs(self, loop_seqs, uv_layer, uv_min, - width, height): - diff_uvs = [] - for hidx, hseq in enumerate(loop_seqs): - pair = hseq[0] - luv0 = pair[0][uv_layer] - luv1 = pair[1][uv_layer] - target_uv0 = Vector((0.0, 0.0)) - target_uv1 = Vector((0.0, 0.0)) - if self.location == 'RIGHT_BOTTOM': - target_uv0.x = target_uv1.x = uv_min.x + width - elif self.location == 'MIDDLE': - target_uv0.x = target_uv1.x = uv_min.x + width * 0.5 - elif self.location == 'LEFT_TOP': - target_uv0.x = target_uv1.x = uv_min.x - if luv0.uv.y < luv1.uv.y: - target_uv0.y = uv_min.y + hidx * height / len(loop_seqs) - target_uv1.y = uv_min.y + (hidx + 1) * height / len(loop_seqs) - else: - target_uv0.y = uv_min.y + (hidx + 1) * height / len(loop_seqs) - target_uv1.y = uv_min.y + hidx * height / len(loop_seqs) - diff_uvs.append([target_uv0 - luv0.uv, target_uv1 - luv1.uv]) - - return diff_uvs - - # only selected UV loop sequence will be aligned along to X-axis - def __align_to_x_axis_wo_transmission(self, loop_seqs, uv_layer, - uv_min, width, height): - # reverse if the UV coordinate is not sorted by position - need_revese = loop_seqs[0][0][0][uv_layer].uv.x > \ - loop_seqs[-1][0][0][uv_layer].uv.x - if need_revese: - loop_seqs.reverse() - for hidx, hseq in enumerate(loop_seqs): - for vidx, pair in enumerate(hseq): - tmp = loop_seqs[hidx][vidx][0] - loop_seqs[hidx][vidx][0] = loop_seqs[hidx][vidx][1] - loop_seqs[hidx][vidx][1] = tmp - - # get UV differential - diff_uvs = self.__get_x_axis_align_diff_uvs(loop_seqs, uv_layer, - uv_min, width, height) - - # update UV - for hseq, duv in zip(loop_seqs, diff_uvs): - pair = hseq[0] - luv0 = pair[0][uv_layer] - luv1 = pair[1][uv_layer] - luv0.uv = luv0.uv + duv[0] - luv1.uv = luv1.uv + duv[1] - - # only selected UV loop sequence will be aligned along to Y-axis - def __align_to_y_axis_wo_transmission(self, loop_seqs, uv_layer, - uv_min, width, height): - # reverse if the UV coordinate is not sorted by position - need_revese = loop_seqs[0][0][0][uv_layer].uv.y > \ - loop_seqs[-1][0][0][uv_layer].uv.y - if need_revese: - loop_seqs.reverse() - for hidx, hseq in enumerate(loop_seqs): - for vidx, pair in enumerate(hseq): - tmp = loop_seqs[hidx][vidx][0] - loop_seqs[hidx][vidx][0] = loop_seqs[hidx][vidx][1] - loop_seqs[hidx][vidx][1] = tmp - - # get UV differential - diff_uvs = self.__get_y_axis_align_diff_uvs(loop_seqs, uv_layer, - uv_min, width, height) - - # update UV - for hseq, duv in zip(loop_seqs, diff_uvs): - pair = hseq[0] - luv0 = pair[0][uv_layer] - luv1 = pair[1][uv_layer] - luv0.uv = luv0.uv + duv[0] - luv1.uv = luv1.uv + duv[1] - - # selected and paralleled UV loop sequence will be aligned along to X-axis - def __align_to_x_axis_w_transmission(self, loop_seqs, uv_layer, - uv_min, width, height): - # reverse if the UV coordinate is not sorted by position - need_revese = loop_seqs[0][0][0][uv_layer].uv.x > \ - loop_seqs[-1][0][0][uv_layer].uv.x - if need_revese: - loop_seqs.reverse() - for hidx, hseq in enumerate(loop_seqs): - for vidx in range(len(hseq)): - tmp = loop_seqs[hidx][vidx][0] - loop_seqs[hidx][vidx][0] = loop_seqs[hidx][vidx][1] - loop_seqs[hidx][vidx][1] = tmp - - # get offset UVs when the UVs are aligned to X-axis - align_diff_uvs = self.__get_x_axis_align_diff_uvs(loop_seqs, uv_layer, - uv_min, width, - height) - base_uv = loop_seqs[0][0][0][uv_layer].uv.copy() - offset_uvs = [] - for hseq, aduv in zip(loop_seqs, align_diff_uvs): - luv0 = hseq[0][0][uv_layer] - luv1 = hseq[0][1][uv_layer] - offset_uvs.append([luv0.uv + aduv[0] - base_uv, - luv1.uv + aduv[1] - base_uv]) - - # get UV differential - diff_uvs = [] - # hseq[vertical][loop] - for hidx, hseq in enumerate(loop_seqs): - # pair[loop] - diffs = [] - for vidx in range(0, len(hseq), 2): - if self.horizontal: - hdiff_uvs = [ - get_hdiff_uv_vinfl(uv_layer, loop_seqs, vidx, hidx, 0, - self.mesh_infl), - get_hdiff_uv_vinfl(uv_layer, loop_seqs, vidx, hidx, 1, - self.mesh_infl), - get_hdiff_uv_vinfl(uv_layer, loop_seqs, vidx + 1, - hidx, 0, self.mesh_infl), - get_hdiff_uv_vinfl(uv_layer, loop_seqs, vidx + 1, - hidx, 1, self.mesh_infl), - ] - hdiff_uvs[0].y = hdiff_uvs[0].y + offset_uvs[hidx][0].y - hdiff_uvs[1].y = hdiff_uvs[1].y + offset_uvs[hidx][1].y - hdiff_uvs[2].y = hdiff_uvs[2].y + offset_uvs[hidx][0].y - hdiff_uvs[3].y = hdiff_uvs[3].y + offset_uvs[hidx][1].y - else: - hdiff_uvs = [ - offset_uvs[hidx][0], - offset_uvs[hidx][1], - offset_uvs[hidx][0], - offset_uvs[hidx][1], - ] - if self.vertical: - vdiff_uvs = [ - get_vdiff_uv_vinfl(uv_layer, loop_seqs, vidx, hidx, 0, - self.mesh_infl), - get_vdiff_uv_vinfl(uv_layer, loop_seqs, vidx, hidx, 1, - self.mesh_infl), - get_vdiff_uv_vinfl(uv_layer, loop_seqs, vidx + 1, - hidx, 0, self.mesh_infl), - get_vdiff_uv_vinfl(uv_layer, loop_seqs, vidx + 1, - hidx, 1, self.mesh_infl), - ] - else: - vdiff_uvs = [ - get_vdiff_uv(uv_layer, loop_seqs, vidx, hidx), - get_vdiff_uv(uv_layer, loop_seqs, vidx, hidx), - get_vdiff_uv(uv_layer, loop_seqs, vidx + 1, hidx), - get_vdiff_uv(uv_layer, loop_seqs, vidx + 1, hidx) - ] - diffs.append([hdiff_uvs, vdiff_uvs]) - diff_uvs.append(diffs) - - # update UV - for hseq, diffs in zip(loop_seqs, diff_uvs): - for vidx in range(0, len(hseq), 2): - loops = [ - hseq[vidx][0], hseq[vidx][1], - hseq[vidx + 1][0], hseq[vidx + 1][1] - ] - for l, hdiff, vdiff in zip(loops, diffs[int(vidx / 2)][0], - diffs[int(vidx / 2)][1]): - l[uv_layer].uv = base_uv + hdiff + vdiff - if self.select: - l[uv_layer].select = True - - # selected and paralleled UV loop sequence will be aligned along to Y-axis - def __align_to_y_axis_w_transmission(self, loop_seqs, uv_layer, - uv_min, width, height): - # reverse if the UV coordinate is not sorted by position - need_revese = loop_seqs[0][0][0][uv_layer].uv.y > \ - loop_seqs[-1][0][-1][uv_layer].uv.y - if need_revese: - loop_seqs.reverse() - for hidx, hseq in enumerate(loop_seqs): - for vidx in range(len(hseq)): - tmp = loop_seqs[hidx][vidx][0] - loop_seqs[hidx][vidx][0] = loop_seqs[hidx][vidx][1] - loop_seqs[hidx][vidx][1] = tmp - - # get offset UVs when the UVs are aligned to Y-axis - align_diff_uvs = self.__get_y_axis_align_diff_uvs(loop_seqs, uv_layer, - uv_min, width, - height) - base_uv = loop_seqs[0][0][0][uv_layer].uv.copy() - offset_uvs = [] - for hseq, aduv in zip(loop_seqs, align_diff_uvs): - luv0 = hseq[0][0][uv_layer] - luv1 = hseq[0][1][uv_layer] - offset_uvs.append([luv0.uv + aduv[0] - base_uv, - luv1.uv + aduv[1] - base_uv]) - - # get UV differential - diff_uvs = [] - # hseq[vertical][loop] - for hidx, hseq in enumerate(loop_seqs): - # pair[loop] - diffs = [] - for vidx in range(0, len(hseq), 2): - if self.horizontal: - hdiff_uvs = [ - get_hdiff_uv_vinfl(uv_layer, loop_seqs, vidx, hidx, 0, - self.mesh_infl), - get_hdiff_uv_vinfl(uv_layer, loop_seqs, vidx, hidx, 1, - self.mesh_infl), - get_hdiff_uv_vinfl(uv_layer, loop_seqs, vidx + 1, - hidx, 0, self.mesh_infl), - get_hdiff_uv_vinfl(uv_layer, loop_seqs, vidx + 1, - hidx, 1, self.mesh_infl), - ] - hdiff_uvs[0].x = hdiff_uvs[0].x + offset_uvs[hidx][0].x - hdiff_uvs[1].x = hdiff_uvs[1].x + offset_uvs[hidx][1].x - hdiff_uvs[2].x = hdiff_uvs[2].x + offset_uvs[hidx][0].x - hdiff_uvs[3].x = hdiff_uvs[3].x + offset_uvs[hidx][1].x - else: - hdiff_uvs = [ - offset_uvs[hidx][0], - offset_uvs[hidx][1], - offset_uvs[hidx][0], - offset_uvs[hidx][1], - ] - if self.vertical: - vdiff_uvs = [ - get_vdiff_uv_vinfl(uv_layer, loop_seqs, vidx, hidx, 0, - self.mesh_infl), - get_vdiff_uv_vinfl(uv_layer, loop_seqs, vidx, hidx, 1, - self.mesh_infl), - get_vdiff_uv_vinfl(uv_layer, loop_seqs, vidx + 1, - hidx, 0, self.mesh_infl), - get_vdiff_uv_vinfl(uv_layer, loop_seqs, vidx + 1, - hidx, 1, self.mesh_infl), - ] - else: - vdiff_uvs = [ - get_vdiff_uv(uv_layer, loop_seqs, vidx, hidx), - get_vdiff_uv(uv_layer, loop_seqs, vidx, hidx), - get_vdiff_uv(uv_layer, loop_seqs, vidx + 1, hidx), - get_vdiff_uv(uv_layer, loop_seqs, vidx + 1, hidx) - ] - diffs.append([hdiff_uvs, vdiff_uvs]) - diff_uvs.append(diffs) - - # update UV - for hseq, diffs in zip(loop_seqs, diff_uvs): - for vidx in range(0, len(hseq), 2): - loops = [ - hseq[vidx][0], hseq[vidx][1], - hseq[vidx + 1][0], hseq[vidx + 1][1] - ] - for l, hdiff, vdiff in zip(loops, diffs[int(vidx / 2)][0], - diffs[int(vidx / 2)][1]): - l[uv_layer].uv = base_uv + hdiff + vdiff - if self.select: - l[uv_layer].select = True - - def __align(self, loop_seqs, uv_layer, uv_min, width, height): - # align along to x-axis - if width > height: - if self.transmission: - self.__align_to_x_axis_w_transmission(loop_seqs, uv_layer, - uv_min, width, height) - else: - self.__align_to_x_axis_wo_transmission(loop_seqs, uv_layer, - uv_min, width, height) - # align along to y-axis - else: - if self.transmission: - self.__align_to_y_axis_w_transmission(loop_seqs, uv_layer, - uv_min, width, height) - else: - self.__align_to_y_axis_wo_transmission(loop_seqs, uv_layer, - uv_min, width, height) + return impl.AxisImpl.poll(context) def execute(self, context): - obj = context.active_object - bm = bmesh.from_edit_mesh(obj.data) - if common.check_version(2, 73, 0) >= 0: - bm.faces.ensure_lookup_table() - uv_layer = bm.loops.layers.uv.verify() - - # loop_seqs[horizontal][vertical][loop] - loop_seqs, error = common.get_loop_sequences(bm, uv_layer) - if not loop_seqs: - self.report({'WARNING'}, error) - return {'CANCELLED'} - - # get height and width - uv_max, uv_min = self.__get_uv_max_min(loop_seqs, uv_layer) - width = uv_max.x - uv_min.x - height = uv_max.y - uv_min.y - - self.__align(loop_seqs, uv_layer, uv_min, width, height) - - bmesh.update_edit_mesh(obj.data) - - return {'FINISHED'} + return self.__impl.execute(self, context) |