diff options
Diffstat (limited to 'uv_magic_uv/op/uvw.py')
-rw-r--r-- | uv_magic_uv/op/uvw.py | 176 |
1 files changed, 34 insertions, 142 deletions
diff --git a/uv_magic_uv/op/uvw.py b/uv_magic_uv/op/uvw.py index 44858187..c97e0e04 100644 --- a/uv_magic_uv/op/uvw.py +++ b/uv_magic_uv/op/uvw.py @@ -23,8 +23,6 @@ __status__ = "production" __version__ = "5.2" __date__ = "17 Nov 2018" -from math import sin, cos, pi - import bpy import bmesh from bpy.props import ( @@ -32,40 +30,24 @@ from bpy.props import ( FloatVectorProperty, BoolProperty ) -from mathutils import Vector from .. import common +from ..impl import uvw_impl as impl +from ..utils.bl_class_registry import BlClassRegistry +from ..utils.property_class_registry import PropertyClassRegistry __all__ = [ 'Properties', - 'OperatorBoxMap', - 'OperatorBestPlanerMap', + 'MUV_OT_UVW_BoxMap', + 'MUV_OT_UVW_BestPlanerMap', ] -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 - - +@PropertyClassRegistry() class Properties: + idname = "uvw" + @classmethod def init_props(cls, scene): scene.muv_uvw_enabled = BoolProperty( @@ -85,32 +67,33 @@ class Properties: del scene.muv_uvw_assign_uvmap -class OperatorBoxMap(bpy.types.Operator): +@BlClassRegistry() +class MUV_OT_UVW_BoxMap(bpy.types.Operator): bl_idname = "uv.muv_uvw_operator_box_map" bl_label = "Box Map" bl_options = {'REGISTER', 'UNDO'} - size = FloatProperty( + size: FloatProperty( name="Size", default=1.0, precision=4 ) - rotation = FloatVectorProperty( + rotation: FloatVectorProperty( name="XYZ Rotation", size=3, default=(0.0, 0.0, 0.0) ) - offset = FloatVectorProperty( + offset: FloatVectorProperty( name="XYZ Offset", size=3, default=(0.0, 0.0, 0.0) ) - tex_aspect = FloatProperty( + tex_aspect: FloatProperty( name="Texture Aspect", default=1.0, precision=4 ) - assign_uvmap = BoolProperty( + assign_uvmap: BoolProperty( name="Assign UVMap", description="Assign UVMap when no UVmaps are available", default=True @@ -121,7 +104,7 @@ class OperatorBoxMap(bpy.types.Operator): # we can not get area/space/region from console if common.is_console_mode(): return True - return is_valid_context(context) + return impl.is_valid_context(context) def execute(self, context): obj = context.active_object @@ -130,102 +113,43 @@ class OperatorBoxMap(bpy.types.Operator): bm.faces.ensure_lookup_table() # get UV layer - if not bm.loops.layers.uv: - if self.assign_uvmap: - bm.loops.layers.uv.new() - else: - self.report( - {'WARNING'}, "Object must have more than one UV map") - return {'CANCELLED'} - uv_layer = bm.loops.layers.uv.verify() - - scale = 1.0 / self.size - - sx = 1.0 * scale - sy = 1.0 * scale - sz = 1.0 * scale - ofx = self.offset[0] - ofy = self.offset[1] - ofz = self.offset[2] - rx = self.rotation[0] * pi / 180.0 - ry = self.rotation[1] * pi / 180.0 - rz = self.rotation[2] * pi / 180.0 - aspect = self.tex_aspect - - sel_faces = [f for f in bm.faces if f.select] - - # update UV coordinate - for f in sel_faces: - n = f.normal - for l in f.loops: - co = l.vert.co - x = co.x * sx - y = co.y * sy - z = co.z * sz - - # X-plane - if abs(n[0]) >= abs(n[1]) and abs(n[0]) >= abs(n[2]): - if n[0] >= 0.0: - u = (y - ofy) * cos(rx) + (z - ofz) * sin(rx) - v = -(y * aspect - ofy) * sin(rx) +\ - (z * aspect - ofz) * cos(rx) - else: - u = -(y - ofy) * cos(rx) + (z - ofz) * sin(rx) - v = (y * aspect - ofy) * sin(rx) +\ - (z * aspect - ofz) * cos(rx) - # Y-plane - elif abs(n[1]) >= abs(n[0]) and abs(n[1]) >= abs(n[2]): - if n[1] >= 0.0: - u = -(x - ofx) * cos(ry) + (z - ofz) * sin(ry) - v = (x * aspect - ofx) * sin(ry) +\ - (z * aspect - ofz) * cos(ry) - else: - u = (x - ofx) * cos(ry) + (z - ofz) * sin(ry) - v = -(x * aspect - ofx) * sin(ry) +\ - (z * aspect - ofz) * cos(ry) - # Z-plane - else: - if n[2] >= 0.0: - u = (x - ofx) * cos(rz) + (y - ofy) * sin(rz) - v = -(x * aspect - ofx) * sin(rz) +\ - (y * aspect - ofy) * cos(rz) - else: - u = -(x - ofx) * cos(rz) - (y + ofy) * sin(rz) - v = -(x * aspect + ofx) * sin(rz) +\ - (y * aspect - ofy) * cos(rz) - - l[uv_layer].uv = Vector((u, v)) + uv_layer = impl.get_uv_layer(self, bm, self.assign_uvmap) + if not uv_layer: + return {'CANCELLED'} + impl.apply_box_map(bm, uv_layer, self.size, self.offset, + self.rotation, self.tex_aspect) bmesh.update_edit_mesh(obj.data) return {'FINISHED'} -class OperatorBestPlanerMap(bpy.types.Operator): +@BlClassRegistry() +class MUV_OT_UVW_BestPlanerMap(bpy.types.Operator): bl_idname = "uv.muv_uvw_operator_best_planer_map" bl_label = "Best Planer Map" bl_options = {'REGISTER', 'UNDO'} - size = FloatProperty( + size: FloatProperty( name="Size", default=1.0, precision=4 ) - rotation = FloatProperty( + rotation: FloatProperty( name="XY Rotation", default=0.0 ) - offset = FloatVectorProperty( + offset: FloatVectorProperty( name="XY Offset", size=2, default=(0.0, 0.0) ) - tex_aspect = FloatProperty( + tex_aspect: FloatProperty( name="Texture Aspect", default=1.0, precision=4 ) - assign_uvmap = BoolProperty( + assign_uvmap: BoolProperty( name="Assign UVMap", description="Assign UVMap when no UVmaps are available", default=True @@ -236,7 +160,7 @@ class OperatorBestPlanerMap(bpy.types.Operator): # we can not get area/space/region from console if common.is_console_mode(): return True - return is_valid_context(context) + return impl.is_valid_context(context) def execute(self, context): obj = context.active_object @@ -245,44 +169,12 @@ class OperatorBestPlanerMap(bpy.types.Operator): bm.faces.ensure_lookup_table() # get UV layer - if not bm.loops.layers.uv: - if self.assign_uvmap: - bm.loops.layers.uv.new() - else: - self.report( - {'WARNING'}, "Object must have more than one UV map") - return {'CANCELLED'} - - uv_layer = bm.loops.layers.uv.verify() - - scale = 1.0 / self.size - - sx = 1.0 * scale - sy = 1.0 * scale - ofx = self.offset[0] - ofy = self.offset[1] - rz = self.rotation * pi / 180.0 - aspect = self.tex_aspect - - sel_faces = [f for f in bm.faces if f.select] - - # calculate average of normal - n_ave = Vector((0.0, 0.0, 0.0)) - for f in sel_faces: - n_ave = n_ave + f.normal - q = n_ave.rotation_difference(Vector((0.0, 0.0, 1.0))) - - # update UV coordinate - for f in sel_faces: - for l in f.loops: - co = q * l.vert.co - x = co.x * sx - y = co.y * sy - - u = x * cos(rz) - y * sin(rz) + ofx - v = -x * aspect * sin(rz) - y * aspect * cos(rz) + ofy + uv_layer = impl.get_uv_layer(self, bm, self.assign_uvmap) + if not uv_layer: + return {'CANCELLED'} - l[uv_layer].uv = Vector((u, v)) + impl.apply_planer_map(bm, uv_layer, self.size, self.offset, + self.rotation, self.tex_aspect) bmesh.update_edit_mesh(obj.data) |