forked from drewcassidy/TexTools-Blender
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathop_align.py
122 lines (92 loc) · 3.82 KB
/
op_align.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import bpy
import bmesh
import operator
from mathutils import Vector
from collections import defaultdict
from math import pi
from . import utilities_uv
class op(bpy.types.Operator):
bl_idname = "uv.textools_align"
bl_label = "Align"
bl_description = "Align vertices, edges or shells"
bl_options = {'REGISTER', 'UNDO'}
direction: bpy.props.StringProperty(name="Direction", default="top")
@classmethod
def poll(cls, context):
if not bpy.context.active_object:
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:
# self.report({'WARNING'}, "Object must have more than one UV map")
return False
# Not in Synced mode
if bpy.context.scene.tool_settings.use_uv_select_sync:
return False
return True
def execute(self, context):
align(context, self.direction)
return {'FINISHED'}
def align(context, direction):
# Store selection
utilities_uv.selection_store()
if bpy.context.tool_settings.transform_pivot_point != 'CURSOR':
bpy.context.tool_settings.transform_pivot_point = 'CURSOR'
# B-Mesh
obj = bpy.context.active_object
bm = bmesh.from_edit_mesh(obj.data)
uv_layers = bm.loops.layers.uv.verify()
if len(obj.data.uv_layers) == 0:
print("There is no UV channel or UV data set")
return
# Collect BBox sizes
boundsAll = utilities_uv.getSelectionBBox()
mode = bpy.context.scene.tool_settings.uv_select_mode
if mode == 'FACE' or mode == 'ISLAND':
print("____ Align Islands")
# Collect UV islands
islands = utilities_uv.getSelectionIslands()
for island in islands:
bpy.ops.uv.select_all(action='DESELECT')
utilities_uv.set_selected_faces(island)
bounds = utilities_uv.getSelectionBBox()
# print("Island "+str(len(island))+"x faces, delta: "+str(delta.y))
if direction == "bottom":
delta = boundsAll['min'] - bounds['min']
bpy.ops.transform.translate(value=(0, delta.y, 0))
elif direction == "top":
delta = boundsAll['max'] - bounds['max']
bpy.ops.transform.translate(value=(0, delta.y, 0))
elif direction == "left":
delta = boundsAll['min'] - bounds['min']
bpy.ops.transform.translate(value=(delta.x, 0, 0))
elif direction == "right":
delta = boundsAll['max'] - bounds['max']
bpy.ops.transform.translate(value=(delta.x, 0, 0))
else:
print("Unkown direction: "+str(direction))
elif mode == 'EDGE' or mode == 'VERTEX':
print("____ Align Verts")
for f in bm.faces:
if f.select:
for l in f.loops:
luv = l[uv_layers]
if luv.select:
# print("Idx: "+str(luv.uv))
if direction == "top":
luv.uv[1] = boundsAll['max'].y
elif direction == "bottom":
luv.uv[1] = boundsAll['min'].y
elif direction == "left":
luv.uv[0] = boundsAll['min'].x
elif direction == "right":
luv.uv[0] = boundsAll['max'].x
bmesh.update_edit_mesh(obj.data)
# Restore selection
utilities_uv.selection_restore()
bpy.utils.register_class(op)