You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Blender-TexTools/op_uv_resize.py

265 lines
8.2 KiB
Python

import bpy
import bmesh
import operator
from mathutils import Vector
from collections import defaultdict
from math import pi
from . import utilities_uv
from . import utilities_ui
from . import utilities_texel
name_texture = "TT_resize_area"
utilities_ui.icon_register("op_extend_canvas_TL_active.png")
utilities_ui.icon_register("op_extend_canvas_TR_active.png")
utilities_ui.icon_register("op_extend_canvas_BL_active.png")
utilities_ui.icon_register("op_extend_canvas_BR_active.png")
def on_dropdown_size_x(self, context):
4 years ago
self.size_x = int(self.dropdown_size_x)
# context.area.tag_redraw()
4 years ago
def on_dropdown_size_y(self, context):
4 years ago
self.size_y = int(self.dropdown_size_y)
# context.area.tag_redraw()
class op(bpy.types.Operator):
4 years ago
bl_idname = "uv.textools_uv_resize"
bl_label = "Resize Area"
bl_description = "Resize or extend the UV area"
bl_options = {'REGISTER', 'UNDO'}
4 years ago
size_x: bpy.props.IntProperty(
name="Width",
4 years ago
description="padding size in pixels",
4 years ago
default=1024,
min=1,
max=8192
4 years ago
)
4 years ago
size_y: bpy.props.IntProperty(
name="Height",
4 years ago
description="padding size in pixels",
4 years ago
default=1024,
min=1,
max=8192
4 years ago
)
4 years ago
dropdown_size_x: bpy.props.EnumProperty(
items=utilities_ui.size_textures,
name="",
update=on_dropdown_size_x,
default='1024'
4 years ago
)
4 years ago
dropdown_size_y: bpy.props.EnumProperty(
items=utilities_ui.size_textures,
name="",
update=on_dropdown_size_y,
default='1024'
4 years ago
)
4 years ago
direction: bpy.props.EnumProperty(name='direction', items=(
('TL', ' ', 'Top Left', utilities_ui.icon_get(
"op_extend_canvas_TL_active"), 0),
('BL', ' ', 'Bottom Left', utilities_ui.icon_get(
"op_extend_canvas_BL_active"), 2),
('TR', ' ', 'Top Right', utilities_ui.icon_get(
"op_extend_canvas_TR_active"), 1),
('BR', ' ', 'Bottom Right', utilities_ui.icon_get(
"op_extend_canvas_BR_active"), 3)
4 years ago
))
4 years ago
4 years ago
@classmethod
def poll(cls, context):
if not bpy.context.active_object:
return False
4 years ago
4 years ago
if bpy.context.active_object.type != 'MESH':
return False
4 years ago
# Only in Edit mode
4 years ago
if bpy.context.active_object.mode != 'EDIT':
return False
4 years ago
# Only in UV editor mode
4 years ago
if bpy.context.area.type != 'IMAGE_EDITOR':
return False
4 years ago
# Requires UV map
4 years ago
if not bpy.context.object.data.uv_layers:
return False
return True
def invoke(self, context, event):
print("Invoke resize area")
self.size_x = bpy.context.scene.texToolsSettings.size[0]
self.size_y = bpy.context.scene.texToolsSettings.size[1]
for item in utilities_ui.size_textures:
if int(item[0]) == self.size_x:
self.dropdown_size_x = item[0]
break
for item in utilities_ui.size_textures:
if int(item[0]) == self.size_y:
self.dropdown_size_y = item[0]
break
4 years ago
return context.window_manager.invoke_props_dialog(self, width=140)
4 years ago
def check(self, context):
return True
def draw(self, context):
# https://b3d.interplanety.org/en/creating-pop-up-panels-with-user-ui-in-blender-add-on/
layout = self.layout
layout.separator()
# New Size
row = layout.row()
split = row.split(factor=0.6)
c = split.column(align=True)
4 years ago
c.prop(self, "size_x", text="X", expand=True)
c.prop(self, "size_y", text="Y", expand=True)
4 years ago
c = split.column(align=True)
c.prop(self, "dropdown_size_x", text="")
c.prop(self, "dropdown_size_y", text="")
# Direction
col = layout.column(align=True)
col.label(text="Direction")
row = col.row(align=True)
4 years ago
row.prop(self, 'direction', expand=True)
4 years ago
# Summary
4 years ago
size_A = "{} x {}".format(
bpy.context.scene.texToolsSettings.size[0], bpy.context.scene.texToolsSettings.size[1])
4 years ago
if bpy.context.scene.texToolsSettings.size[0] == bpy.context.scene.texToolsSettings.size[1]:
size_A = "{}²".format(bpy.context.scene.texToolsSettings.size[0])
size_B = "{} x {}".format(self.size_x, self.size_y)
if self.size_x == self.size_y:
size_B = "{}²".format(self.size_x)
layout.label(text="{} to {}".format(
size_A, size_B
))
layout.separator()
def execute(self, context):
4 years ago
# Store selection
4 years ago
utilities_uv.selection_store()
# Get start and end size
4 years ago
size_A = Vector([
4 years ago
bpy.context.scene.texToolsSettings.size[0],
bpy.context.scene.texToolsSettings.size[1]
])
4 years ago
size_B = Vector([
4 years ago
self.size_x,
self.size_y
])
resize_uv(
self,
context,
self.direction,
4 years ago
size_A,
4 years ago
size_B
)
resize_image(
context,
self.direction,
size_A,
size_B
)
4 years ago
bpy.context.scene.texToolsSettings.size[0] = self.size_x
bpy.context.scene.texToolsSettings.size[1] = self.size_y
4 years ago
# Restore selection
4 years ago
utilities_uv.selection_restore()
4 years ago
return {'FINISHED'}
def resize_uv(self, context, mode, size_A, size_B):
4 years ago
# Set pivot
bpy.context.tool_settings.transform_pivot_point = 'CURSOR'
if mode == 'TL':
4 years ago
bpy.ops.uv.cursor_set(location=Vector([0, 1]))
4 years ago
elif mode == 'TR':
4 years ago
bpy.ops.uv.cursor_set(location=Vector([1, 1]))
4 years ago
elif mode == 'BL':
4 years ago
bpy.ops.uv.cursor_set(location=Vector([0, 0]))
4 years ago
elif mode == 'BR':
4 years ago
bpy.ops.uv.cursor_set(location=Vector([1, 0]))
4 years ago
# Select all UV faces
bpy.ops.uv.select_all(action='SELECT')
4 years ago
# Resize
scale_x = size_A.x / size_B.x
scale_y = size_A.y / size_B.y
4 years ago
bpy.ops.transform.resize(
value=(scale_x, scale_y, 1.0), use_proportional_edit=False)
def resize_image(context, mode, size_A, size_B):
4 years ago
print("resize image {}".format(context.area.spaces))
4 years ago
# Notes: https://blender.stackexchange.com/questions/31514/active-image-of-uv-image-editor
# https://docs.blender.org/api/blender_python_api_2_70_4/bpy.types.SpaceImageEditor.html
if context.area.spaces.active != None:
if context.area.spaces.active.image != None:
image = context.area.spaces.active.image
4 years ago
image_obj = utilities_texel.get_object_texture_image(
bpy.context.active_object)
4 years ago
if name_texture in image.name or image == image_obj:
# Resize Image UV editor background image
4 years ago
utilities_texel.image_resize(
image, int(size_B.x), int(size_B.y))
4 years ago
else:
# No Image assigned
# Get background color from theme + 1.25x brighter
theme = bpy.context.preferences.themes[0]
color = theme.image_editor.space.back.copy()
4 years ago
color.r *= 1.15
color.g *= 1.15
color.b *= 1.15
4 years ago
image = None
if name_texture in bpy.data.images:
# TexTools Image already exists
image = bpy.data.images[name_texture]
4 years ago
image.scale(int(size_B.x), int(size_B.y))
4 years ago
image.generated_width = int(size_B.x)
image.generated_height = int(size_B.y)
else:
# Create new image
4 years ago
image = bpy.data.images.new(
name_texture, width=int(size_B.x), height=int(size_B.y))
4 years ago
image.generated_color = (color.r, color.g, color.b, 1.0)
image.generated_type = 'BLANK'
image.generated_width = int(size_B.x)
image.generated_height = int(size_B.y)
# Assign in UV view
context.area.spaces.active.image = image
# Clean up images and materials
utilities_texel.checker_images_cleanup()
4 years ago
bpy.utils.register_class(op)