Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'uv_magic_uv/legacy/op/align_uv.py')
-rw-r--r--uv_magic_uv/legacy/op/align_uv.py791
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)