-
Notifications
You must be signed in to change notification settings - Fork 142
/
Copy pathop_align.py
143 lines (99 loc) · 3.48 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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import bpy
import bmesh
import operator
from mathutils import Vector
from collections import defaultdict
from math import pi, sqrt
from numpy import median
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:
return False #self.report({'WARNING'}, "Object must have more than one UV map")
# 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()
center_all = boundsAll['center']
mode = bpy.context.scene.tool_settings.uv_select_mode
if mode == 'FACE' or mode == 'ISLAND':
#Collect UV islands
islands = utilities_uv.getSelectionIslands()
for island in islands:
bounds = utilities_uv.get_island_BBOX(island)
center = bounds['center']
if direction == "bottom":
delta = boundsAll['min'] - bounds['min']
utilities_uv.move_island(island, 0,delta.y)
elif direction == "top":
delta = boundsAll['max'] - bounds['max']
utilities_uv.move_island(island, 0,delta.y)
elif direction == "left":
delta = boundsAll['min'] - bounds['min']
utilities_uv.move_island(island, delta.x,0)
elif direction == "right":
delta = boundsAll['max'] - bounds['max']
utilities_uv.move_island(island, delta.x,0)
elif direction == "center":
delta = Vector((center_all - center))
utilities_uv.move_island(island, delta.x, delta.y)
elif direction == "horizontal":
delta = Vector((center_all - center))
utilities_uv.move_island(island, 0, delta.y)
elif direction == "vertical":
delta = Vector((center_all - center))
utilities_uv.move_island(island, delta.x, 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)