diff options
Diffstat (limited to 'magic_uv/op/mirror_uv.py')
-rw-r--r-- | magic_uv/op/mirror_uv.py | 96 |
1 files changed, 85 insertions, 11 deletions
diff --git a/magic_uv/op/mirror_uv.py b/magic_uv/op/mirror_uv.py index a893ab83..969c26dc 100644 --- a/magic_uv/op/mirror_uv.py +++ b/magic_uv/op/mirror_uv.py @@ -20,8 +20,8 @@ __author__ = "Keith (Wahooney) Boshoff, Nutti <nutti.metro@gmail.com>" __status__ = "production" -__version__ = "6.4" -__date__ = "23 Oct 2020" +__version__ = "6.5" +__date__ = "6 Mar 2021" import bpy from bpy.props import ( @@ -30,7 +30,7 @@ from bpy.props import ( BoolProperty, ) import bmesh -from mathutils import Vector +from mathutils import Vector, Euler from ..utils.bl_class_registry import BlClassRegistry from ..utils.property_class_registry import PropertyClassRegistry @@ -65,15 +65,15 @@ def _is_vector_similar(v1, v2, error): return within_err_x and within_err_y and within_err_z -def _mirror_uvs(uv_layer, src, dst, axis, error): +def _mirror_uvs(uv_layer, src, dst, axis, error, transformed): """ Copy UV coordinates from one UV face to another """ for sl in src.loops: suv = sl[uv_layer].uv.copy() - svco = sl.vert.co.copy() + svco = transformed[sl.vert].copy() for dl in dst.loops: - dvco = dl.vert.co.copy() + dvco = transformed[dl.vert].copy() if axis == 'X': dvco.x = -dvco.x elif axis == 'Y': @@ -85,13 +85,14 @@ def _mirror_uvs(uv_layer, src, dst, axis, error): dl[uv_layer].uv = suv.copy() -def _get_face_center(face): +def _get_face_center(face, transformed): """ Get center coordinate of the face """ center = Vector((0.0, 0.0, 0.0)) for v in face.verts: - center = center + v.co + tv = transformed[v] + center = center + tv return center / len(face.verts) @@ -117,11 +118,22 @@ class _Properties: description="Mirror Axis", default='X' ) + scene.muv_mirror_uv_origin = EnumProperty( + items=( + ('WORLD', "World", "World"), + ("GLOBAL", "Global", "Global"), + ('LOCAL', "Local", "Local"), + ), + name="Origin", + description="Origin of the mirror operation", + default='LOCAL' + ) @classmethod def del_props(cls, scene): del scene.muv_mirror_uv_enabled del scene.muv_mirror_uv_axis + del scene.muv_mirror_uv_origin @BlClassRegistry() @@ -154,6 +166,16 @@ class MUV_OT_MirrorUV(bpy.types.Operator): soft_min=0.0, soft_max=1.0 ) + origin = EnumProperty( + items=( + ('WORLD', "World", "World"), + ("GLOBAL", "Global", "Global"), + ('LOCAL', "Local", "Local"), + ), + name="Origin", + description="Origin of the mirror operation", + default='LOCAL' + ) @classmethod def poll(cls, context): @@ -162,6 +184,51 @@ class MUV_OT_MirrorUV(bpy.types.Operator): return True return _is_valid_context(context) + def _get_world_vertices(self, obj, bm): + # Get world orientation matrix. + world_orientation_mat = obj.matrix_world + + # Move to local to world. + transformed = {} + for v in bm.verts: + transformed[v] = compat.matmul(world_orientation_mat, v.co) + + return transformed + + def _get_global_vertices(self, obj, bm): + # Get world rotation matrix. + eular = Euler(obj.rotation_euler) + rotation_mat = eular.to_matrix() + + # Get center location of all verticies. + center_location = Vector((0.0, 0.0, 0.0)) + for v in bm.verts: + center_location += v.co + center_location /= len(bm.verts) + + # Move to local to global. + transformed = {} + for v in bm.verts: + transformed[v] = compat.matmul(rotation_mat, v.co) + transformed[v] -= center_location + + return transformed + + def _get_local_vertices(self, _, bm): + transformed = {} + + # Get center location of all verticies. + center_location = Vector((0.0, 0.0, 0.0)) + for v in bm.verts: + center_location += v.co + center_location /= len(bm.verts) + + for v in bm.verts: + transformed[v] = v.co.copy() + transformed[v] -= center_location + + return transformed + def execute(self, context): objs = common.get_uv_editable_objects(context) @@ -180,6 +247,13 @@ class MUV_OT_MirrorUV(bpy.types.Operator): return {'CANCELLED'} uv_layer = bm.loops.layers.uv.verify() + if self.origin == 'WORLD': + transformed_verts = self._get_world_vertices(obj, bm) + elif self.origin == 'GLOBAL': + transformed_verts = self._get_global_vertices(obj, bm) + elif self.origin == 'LOCAL': + transformed_verts = self._get_local_vertices(obj, bm) + faces = [f for f in bm.faces if f.select] for f_dst in faces: count = len(f_dst.verts) @@ -191,8 +265,8 @@ class MUV_OT_MirrorUV(bpy.types.Operator): continue # test if the vertices x values are the same sign - dst = _get_face_center(f_dst) - src = _get_face_center(f_src) + dst = _get_face_center(f_dst, transformed_verts) + src = _get_face_center(f_src, transformed_verts) if (dst.x > 0 and src.x > 0) or (dst.x < 0 and src.x < 0): continue @@ -207,7 +281,7 @@ class MUV_OT_MirrorUV(bpy.types.Operator): # do mirror UV if _is_vector_similar(dst, src, error): _mirror_uvs(uv_layer, f_src, f_dst, - self.axis, self.error) + self.axis, self.error, transformed_verts) bmesh.update_edit_mesh(obj.data) |