TexTools is a UV and Texture tool set for 3dsMax created several years ago. This open repository will port in time several of the UV tools to Blender in python. http://renderhjs.net/textools/blender
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

264 lines
8.2 KiB

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):
self.size_x = int(self.dropdown_size_x)
# context.area.tag_redraw()
def on_dropdown_size_y(self, context):
self.size_y = int(self.dropdown_size_y)
# context.area.tag_redraw()
class op(bpy.types.Operator):
bl_idname = "uv.textools_uv_resize"
bl_label = "Resize Area"
bl_description = "Resize or extend the UV area"
bl_options = {'REGISTER', 'UNDO'}
size_x: bpy.props.IntProperty(
name="Width",
description="padding size in pixels",
default=1024,
min=1,
max=8192
)
size_y: bpy.props.IntProperty(
name="Height",
description="padding size in pixels",
default=1024,
min=1,
max=8192
)
dropdown_size_x: bpy.props.EnumProperty(
items=utilities_ui.size_textures,
name="",
update=on_dropdown_size_x,
default='1024'
)
dropdown_size_y: bpy.props.EnumProperty(
items=utilities_ui.size_textures,
name="",
update=on_dropdown_size_y,
default='1024'
)
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)
))
@classmethod
def poll(cls, context):
if not bpy.context.active_object:
return False
if bpy.context.active_object.type != 'MESH':
return False
# Only in Edit mode
if bpy.context.active_object.mode != 'EDIT':
return False
# Only in UV editor mode
if bpy.context.area.type != 'IMAGE_EDITOR':
return False
# Requires UV map
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
return context.window_manager.invoke_props_dialog(self, width=140)
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)
c.prop(self, "size_x", text="X", expand=True)
c.prop(self, "size_y", text="Y", expand=True)
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)
row.prop(self, 'direction', expand=True)
# Summary
size_A = "{} x {}".format(
bpy.context.scene.texToolsSettings.size[0], bpy.context.scene.texToolsSettings.size[1])
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):
# Store selection
utilities_uv.selection_store()
# Get start and end size
size_A = Vector([
bpy.context.scene.texToolsSettings.size[0],
bpy.context.scene.texToolsSettings.size[1]
])
size_B = Vector([
self.size_x,
self.size_y
])
resize_uv(
self,
context,
self.direction,
size_A,
size_B
)
resize_image(
context,
self.direction,
size_A,
size_B
)
bpy.context.scene.texToolsSettings.size[0] = self.size_x
bpy.context.scene.texToolsSettings.size[1] = self.size_y
# Restore selection
utilities_uv.selection_restore()
return {'FINISHED'}
def resize_uv(self, context, mode, size_A, size_B):
# Set pivot
bpy.context.tool_settings.transform_pivot_point = 'CURSOR'
if mode == 'TL':
bpy.ops.uv.cursor_set(location=Vector([0, 1]))
elif mode == 'TR':
bpy.ops.uv.cursor_set(location=Vector([1, 1]))
elif mode == 'BL':
bpy.ops.uv.cursor_set(location=Vector([0, 0]))
elif mode == 'BR':
bpy.ops.uv.cursor_set(location=Vector([1, 0]))
# Select all UV faces
bpy.ops.uv.select_all(action='SELECT')
# Resize
scale_x = size_A.x / size_B.x
scale_y = size_A.y / size_B.y
bpy.ops.transform.resize(
value=(scale_x, scale_y, 1.0), use_proportional_edit=False)
def resize_image(context, mode, size_A, size_B):
print("resize image {}".format(context.area.spaces))
# 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
image_obj = utilities_texel.get_object_texture_image(
bpy.context.active_object)
if name_texture in image.name or image == image_obj:
# Resize Image UV editor background image
utilities_texel.image_resize(
image, int(size_B.x), int(size_B.y))
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()
color.r *= 1.15
color.g *= 1.15
color.b *= 1.15
image = None
if name_texture in bpy.data.images:
# TexTools Image already exists
image = bpy.data.images[name_texture]
image.scale(int(size_B.x), int(size_B.y))
image.generated_width = int(size_B.x)
image.generated_height = int(size_B.y)
else:
# Create new image
image = bpy.data.images.new(
name_texture, width=int(size_B.x), height=int(size_B.y))
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()
bpy.utils.register_class(op)