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_fill.py

117 lines
3.6 KiB
Python

import bpy
import bmesh
import operator
import math
from mathutils import Vector
from collections import defaultdict
from . import utilities_uv
from . import utilities_ui
class op(bpy.types.Operator):
4 years ago
bl_idname = "uv.textools_uv_fill"
bl_label = "Fill"
bl_description = "Fill UV selection to UV canvas"
bl_options = {'REGISTER', 'UNDO'}
@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 execute(self, context):
fill(self, context)
return {'FINISHED'}
def fill(self, context):
4 years ago
#Store selection
utilities_uv.selection_store()
4 years ago
bm = bmesh.from_edit_mesh(bpy.context.active_object.data);
uv_layers = bm.loops.layers.uv.verify();
4 years ago
# 1.) Rotate minimal bounds (less than 45 degrees rotation)
steps = 8
angle = 45; # Starting Angle, half each step
bboxPrevious = utilities_uv.getSelectionBBox()
for i in range(0, steps):
# Rotate right
bpy.ops.transform.rotate(value=(angle * math.pi / 180), orient_axis='Z')
bbox = utilities_uv.getSelectionBBox()
4 years ago
print("Rotate {}, diff le: {}".format(angle, bbox['height'] - bboxPrevious['height']))
4 years ago
if i == 0:
# Check if already squared
sizeA = bboxPrevious['width'] * bboxPrevious['height']
sizeB = bbox['width'] * bbox['height']
if abs(bbox['width'] - bbox['height']) <= 0.0001 and sizeA < sizeB:
bpy.ops.transform.rotate(value=(-angle * math.pi / 180), orient_axis='Z')
break;
4 years ago
if bbox['minLength'] < bboxPrevious['minLength']:
bboxPrevious = bbox; # Success
else:
# Rotate Left
bpy.ops.transform.rotate(value=(-angle*2 * math.pi / 180), orient_axis='Z')
bbox = utilities_uv.getSelectionBBox()
if bbox['minLength'] < bboxPrevious['minLength']:
bboxPrevious = bbox; # Success
else:
# Restore angle of this iteration
bpy.ops.transform.rotate(value=(angle * math.pi / 180), orient_axis='Z')
4 years ago
angle = angle / 2
4 years ago
if bboxPrevious['width'] < bboxPrevious['height']:
bpy.ops.transform.rotate(value=(90 * math.pi / 180), orient_axis='Z')
4 years ago
# 2.) Match width and height to UV bounds
bbox = utilities_uv.getSelectionBBox()
4 years ago
scale_x = 1.0 / bbox['width']
scale_y = 1.0 / bbox['height']
print("Scale {} | {}".format(scale_x, scale_y))
4 years ago
bpy.context.tool_settings.transform_pivot_point = 'BOUNDING_BOX_CENTER'
bpy.ops.transform.resize(value=(scale_x, scale_y, 1), constraint_axis=(False, False, False), orient_type='GLOBAL', use_proportional_edit=False)
4 years ago
bbox = utilities_uv.getSelectionBBox()
offset_x = -bbox['min'].x
offset_y = -bbox['min'].y
bpy.ops.transform.translate(value=(offset_x, offset_y, 0), constraint_axis=(False, False, False), orient_type='GLOBAL', use_proportional_edit=False)
4 years ago
#Restore selection
utilities_uv.selection_restore()
bpy.utils.register_class(op)