diff options
Diffstat (limited to 'uv_magic_uv/impl/move_uv_impl.py')
-rw-r--r-- | uv_magic_uv/impl/move_uv_impl.py | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/uv_magic_uv/impl/move_uv_impl.py b/uv_magic_uv/impl/move_uv_impl.py new file mode 100644 index 00000000..ce507fba --- /dev/null +++ b/uv_magic_uv/impl/move_uv_impl.py @@ -0,0 +1,166 @@ +# <pep8-80 compliant> + +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +__author__ = "imdjs, Nutti <nutti.metro@gmail.com>" +__status__ = "production" +__version__ = "5.2" +__date__ = "17 Nov 2018" + +import bmesh +from mathutils import Vector + +from .. import common + + +__all__ = [ + 'is_valid_context', + 'find_uv', + 'MoveUVImpl', +] + + +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 + + # only 'VIEW_3D' space is allowed to execute + for space in context.area.spaces: + if space.type == 'VIEW_3D': + break + else: + return False + + return True + + +def find_uv(context): + bm = bmesh.from_edit_mesh(context.object.data) + topology_dict = [] + uvs = [] + active_uv = bm.loops.layers.uv.active + for fidx, f in enumerate(bm.faces): + for vidx, v in enumerate(f.verts): + if v.select: + uvs.append(f.loops[vidx][active_uv].uv.copy()) + topology_dict.append([fidx, vidx]) + + return topology_dict, uvs + + +class MoveUVImpl(): + __running = False + + def __init__(self): + self.__topology_dict = [] + self.__prev_mouse = Vector((0.0, 0.0)) + self.__offset_uv = Vector((0.0, 0.0)) + self.__prev_offset_uv = Vector((0.0, 0.0)) + self.__first_time = True + self.__ini_uvs = [] + self.__operating = False + + @classmethod + def poll(cls, context): + # we can not get area/space/region from console + if common.is_console_mode(): + return False + if cls.is_running(context): + return False + return is_valid_context(context) + + @classmethod + def is_running(cls, _): + return cls.__running + + def modal(self, _, context, event): + if self.__first_time is True: + self.__prev_mouse = Vector(( + event.mouse_region_x, event.mouse_region_y)) + self.__first_time = False + return {'RUNNING_MODAL'} + + # move UV + div = 10000 + self.__offset_uv += Vector(( + (event.mouse_region_x - self.__prev_mouse.x) / div, + (event.mouse_region_y - self.__prev_mouse.y) / div)) + ouv = self.__offset_uv + pouv = self.__prev_offset_uv + vec = Vector((ouv.x - ouv.y, ouv.x + ouv.y)) + dv = vec - pouv + self.__prev_offset_uv = vec + self.__prev_mouse = Vector(( + event.mouse_region_x, event.mouse_region_y)) + + # check if operation is started + if not self.__operating: + if event.type == 'LEFTMOUSE' and event.value == 'RELEASE': + self.__operating = True + return {'RUNNING_MODAL'} + + # update UV + obj = context.object + bm = bmesh.from_edit_mesh(obj.data) + active_uv = bm.loops.layers.uv.active + for fidx, vidx in self.__topology_dict: + l = bm.faces[fidx].loops[vidx] + l[active_uv].uv = l[active_uv].uv + dv + bmesh.update_edit_mesh(obj.data) + + # check mouse preference + if context.user_preferences.inputs.select_mouse == 'RIGHT': + confirm_btn = 'LEFTMOUSE' + cancel_btn = 'RIGHTMOUSE' + else: + confirm_btn = 'RIGHTMOUSE' + cancel_btn = 'LEFTMOUSE' + + # cancelled + if event.type == cancel_btn and event.value == 'PRESS': + for (fidx, vidx), uv in zip(self.__topology_dict, self.__ini_uvs): + bm.faces[fidx].loops[vidx][active_uv].uv = uv + MoveUVImpl.__running = False + return {'FINISHED'} + # confirmed + if event.type == confirm_btn and event.value == 'PRESS': + MoveUVImpl.__running = False + return {'FINISHED'} + + return {'RUNNING_MODAL'} + + def execute(self, ops_obj, context): + MoveUVImpl.__running = True + self.__operating = False + self.__first_time = True + + context.window_manager.modal_handler_add(ops_obj) + self.__topology_dict, self.__ini_uvs = find_uv(context) + + if context.area: + context.area.tag_redraw() + + return {'RUNNING_MODAL'} |