1 # SPDX-License-Identifier: GPL-2.0-or-later
4 "name": "Hotkey: 'Alt X'",
5 "description": "V/E/F Align tools",
6 "author": "pitiwazou, meta-androcto",
9 "location": "Mesh Edit Mode",
12 "category": "Edit Align Pie"
16 from bpy
.types
import (
20 from bpy
.props
import EnumProperty
24 class PIE_MT_Align(Menu
):
25 bl_idname
= "PIE_MT_align"
26 bl_label
= "Pie Align"
28 def draw(self
, context
):
30 pie
= layout
.menu_pie()
32 box
= pie
.split().box().column()
34 row
= box
.row(align
=True)
36 align_1
= row
.operator("alignxyz.all", text
="Neg")
38 align_1
.side
= 'NEGATIVE'
40 row
= box
.row(align
=True)
42 align_3
= row
.operator("alignxyz.all", text
="Neg")
44 align_3
.side
= 'NEGATIVE'
46 row
= box
.row(align
=True)
48 align_5
= row
.operator("alignxyz.all", text
="Neg")
50 align_5
.side
= 'NEGATIVE'
52 box
= pie
.split().box().column()
54 row
= box
.row(align
=True)
56 align_2
= row
.operator("alignxyz.all", text
="Pos")
58 align_2
.side
= 'POSITIVE'
60 row
= box
.row(align
=True)
62 align_4
= row
.operator("alignxyz.all", text
="Pos")
64 align_4
.side
= 'POSITIVE'
66 row
= box
.row(align
=True)
68 align_6
= row
.operator("alignxyz.all", text
="Pos")
70 align_6
.side
= 'POSITIVE'
72 pie
.operator("align.2xyz", text
="Align To Y-0").axis
= '1'
74 pie
.operator("align.selected2xyz",
75 text
="Align Y").axis
= 'Y'
77 pie
.operator("align.selected2xyz",
78 text
="Align X").axis
= 'X'
80 pie
.operator("align.selected2xyz",
81 text
="Align Z").axis
= 'Z'
83 pie
.operator("align.2xyz", text
="Align To X-0").axis
= '0'
85 pie
.operator("align.2xyz", text
="Align To Z-0").axis
= '2'
89 class PIE_OT_AlignSelectedXYZ(Operator
):
90 bl_idname
= "align.selected2xyz"
91 bl_label
= "Align to X, Y, Z"
92 bl_description
= "Align Selected Along the chosen axis"
93 bl_options
= {'REGISTER', 'UNDO'}
102 description
="Choose an axis for alignment",
107 def poll(cls
, context
):
108 obj
= context
.active_object
109 return obj
and obj
.type == "MESH"
111 def execute(self
, context
):
113 'X': [(0, 1, 1), (True, False, False)],
114 'Y': [(1, 0, 1), (False, True, False)],
115 'Z': [(1, 1, 0), (False, False, True)]
117 chosen_value
= values
[self
.axis
][0]
118 constraint_value
= values
[self
.axis
][1]
119 bpy
.ops
.transform
.resize(
121 constraint_axis
=constraint_value
,
122 orient_type
='GLOBAL',
124 use_proportional_edit
=False,
129 # ################# #
131 # ################# #
133 class PIE_OT_AlignToXYZ0(Operator
):
134 bl_idname
= "align.2xyz"
135 bl_label
= "Align To X, Y or Z = 0"
136 bl_description
= "Align Active Object To a chosen X, Y or Z equals 0 Location"
137 bl_options
= {'REGISTER', 'UNDO'}
142 ('0', "X", "X Axis"),
143 ('1', "Y", "Y Axis"),
146 description
="Choose an axis for alignment",
151 def poll(cls
, context
):
152 obj
= context
.active_object
153 return obj
and obj
.type == "MESH"
155 def execute(self
, context
):
156 bpy
.ops
.object.mode_set(mode
='OBJECT')
157 align
= int(self
.axis
)
158 for vert
in bpy
.context
.object.data
.vertices
:
161 bpy
.ops
.object.editmode_toggle()
167 class PIE_OT_AlignXYZAll(Operator
):
168 bl_idname
= "alignxyz.all"
169 bl_label
= "Align to Front/Back Axis"
170 bl_description
= "Align to a Front or Back along the chosen Axis"
171 bl_options
= {'REGISTER', 'UNDO'}
176 ('0', "X", "X Axis"),
177 ('1', "Y", "Y Axis"),
180 description
="Choose an axis for alignment",
186 ('POSITIVE', "Front", "Align on the positive chosen axis"),
187 ('NEGATIVE', "Back", "Align acriss the negative chosen axis"),
189 description
="Choose a side for alignment",
194 def poll(cls
, context
):
195 obj
= context
.active_object
196 return obj
and obj
.type == "MESH"
198 def execute(self
, context
):
200 bpy
.ops
.object.mode_set(mode
='OBJECT')
203 for vert
in bpy
.context
.object.data
.vertices
:
210 if self
.side
== 'POSITIVE':
211 if vert
.co
[axe
] > maxv
:
214 if vert
.co
[axe
] < maxv
:
217 bpy
.ops
.object.mode_set(mode
='OBJECT')
219 for vert
in bpy
.context
.object.data
.vertices
:
222 bpy
.ops
.object.mode_set(mode
='EDIT')
229 PIE_OT_AlignSelectedXYZ
,
239 bpy
.utils
.register_class(cls
)
241 wm
= bpy
.context
.window_manager
242 if wm
.keyconfigs
.addon
:
244 km
= wm
.keyconfigs
.addon
.keymaps
.new(name
='Mesh')
245 kmi
= km
.keymap_items
.new('wm.call_menu_pie', 'X', 'PRESS', alt
=True)
246 kmi
.properties
.name
= "PIE_MT_align"
247 addon_keymaps
.append((km
, kmi
))
252 bpy
.utils
.unregister_class(cls
)
254 wm
= bpy
.context
.window_manager
255 kc
= wm
.keyconfigs
.addon
257 for km
, kmi
in addon_keymaps
:
258 km
.keymap_items
.remove(kmi
)
259 addon_keymaps
.clear()
262 if __name__
== "__main__":