1 # SPDX-FileCopyrightText: 2016-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
6 "name": "Hotkey: 'Alt X'",
7 "description": "V/E/F Align tools",
8 "author": "pitiwazou, meta-androcto",
10 "blender": (2, 80, 0),
11 "location": "Mesh Edit Mode",
14 "category": "Edit Align Pie"
18 from bpy
.types
import (
22 from bpy
.props
import EnumProperty
26 class PIE_MT_Align(Menu
):
27 bl_idname
= "PIE_MT_align"
28 bl_label
= "Pie Align"
30 def draw(self
, context
):
32 pie
= layout
.menu_pie()
34 box
= pie
.split().box().column()
36 row
= box
.row(align
=True)
38 align_1
= row
.operator("alignxyz.all", text
="Neg")
40 align_1
.side
= 'NEGATIVE'
42 row
= box
.row(align
=True)
44 align_3
= row
.operator("alignxyz.all", text
="Neg")
46 align_3
.side
= 'NEGATIVE'
48 row
= box
.row(align
=True)
50 align_5
= row
.operator("alignxyz.all", text
="Neg")
52 align_5
.side
= 'NEGATIVE'
54 box
= pie
.split().box().column()
56 row
= box
.row(align
=True)
58 align_2
= row
.operator("alignxyz.all", text
="Pos")
60 align_2
.side
= 'POSITIVE'
62 row
= box
.row(align
=True)
64 align_4
= row
.operator("alignxyz.all", text
="Pos")
66 align_4
.side
= 'POSITIVE'
68 row
= box
.row(align
=True)
70 align_6
= row
.operator("alignxyz.all", text
="Pos")
72 align_6
.side
= 'POSITIVE'
74 pie
.operator("align.2xyz", text
="Align To Y-0").axis
= '1'
76 pie
.operator("align.selected2xyz", text
="Align Y").axis
= 'Y'
78 pie
.operator("align.selected2xyz", text
="Align X").axis
= 'X'
80 pie
.operator("align.selected2xyz", text
="Align Z").axis
= 'Z'
82 pie
.operator("align.2xyz", text
="Align To X-0").axis
= '0'
84 pie
.operator("align.2xyz", text
="Align To Z-0").axis
= '2'
88 class PIE_OT_AlignSelectedXYZ(Operator
):
89 bl_idname
= "align.selected2xyz"
90 bl_label
= "Align to X, Y, Z"
91 bl_description
= "Align Selected Along the chosen axis"
92 bl_options
= {'REGISTER', 'UNDO'}
101 description
="Choose an axis for alignment",
106 def poll(cls
, context
):
107 obj
= context
.active_object
108 return obj
and obj
.type == "MESH"
110 def execute(self
, context
):
112 'X': [(0, 1, 1), (True, False, False)],
113 'Y': [(1, 0, 1), (False, True, False)],
114 'Z': [(1, 1, 0), (False, False, True)],
116 chosen_value
= values
[self
.axis
][0]
117 constraint_value
= values
[self
.axis
][1]
118 bpy
.ops
.transform
.resize(
120 constraint_axis
=constraint_value
,
121 orient_type
='GLOBAL',
123 use_proportional_edit
=False,
128 # ################# #
130 # ################# #
132 class PIE_OT_AlignToXYZ0(Operator
):
133 bl_idname
= "align.2xyz"
134 bl_label
= "Align To X, Y or Z = 0"
135 bl_description
= "Align Active Object To a chosen X, Y or Z equals 0 Location"
136 bl_options
= {'REGISTER', 'UNDO'}
141 ('0', "X", "X Axis"),
142 ('1', "Y", "Y Axis"),
143 ('2', "Z", "Z Axis"),
145 description
="Choose an axis for alignment",
150 def poll(cls
, context
):
151 obj
= context
.active_object
152 return obj
and obj
.type == "MESH"
154 def execute(self
, context
):
155 bpy
.ops
.object.mode_set(mode
='OBJECT')
156 align
= int(self
.axis
)
157 for vert
in bpy
.context
.object.data
.vertices
:
160 bpy
.ops
.object.editmode_toggle()
166 class PIE_OT_AlignXYZAll(Operator
):
167 bl_idname
= "alignxyz.all"
168 bl_label
= "Align to Front/Back Axis"
169 bl_description
= "Align to a Front or Back along the chosen Axis"
170 bl_options
= {'REGISTER', 'UNDO'}
175 ('0', "X", "X Axis"),
176 ('1', "Y", "Y Axis"),
177 ('2', "Z", "Z Axis"),
179 description
="Choose an axis for alignment",
185 ('POSITIVE', "Front", "Align on the positive chosen axis"),
186 ('NEGATIVE', "Back", "Align acriss the negative chosen axis"),
188 description
="Choose a side for alignment",
193 def poll(cls
, context
):
194 obj
= context
.active_object
195 return obj
and obj
.type == "MESH"
197 def execute(self
, context
):
199 bpy
.ops
.object.mode_set(mode
='OBJECT')
202 for vert
in bpy
.context
.object.data
.vertices
:
209 if self
.side
== 'POSITIVE':
210 if vert
.co
[axe
] > maxv
:
213 if vert
.co
[axe
] < maxv
:
216 bpy
.ops
.object.mode_set(mode
='OBJECT')
218 for vert
in bpy
.context
.object.data
.vertices
:
221 bpy
.ops
.object.mode_set(mode
='EDIT')
228 PIE_OT_AlignSelectedXYZ
,
238 bpy
.utils
.register_class(cls
)
240 wm
= bpy
.context
.window_manager
241 if wm
.keyconfigs
.addon
:
243 km
= wm
.keyconfigs
.addon
.keymaps
.new(name
='Mesh')
244 kmi
= km
.keymap_items
.new('wm.call_menu_pie', 'X', 'PRESS', alt
=True)
245 kmi
.properties
.name
= "PIE_MT_align"
246 addon_keymaps
.append((km
, kmi
))
251 bpy
.utils
.unregister_class(cls
)
253 wm
= bpy
.context
.window_manager
254 kc
= wm
.keyconfigs
.addon
256 for km
, kmi
in addon_keymaps
:
257 km
.keymap_items
.remove(kmi
)
258 addon_keymaps
.clear()
261 if __name__
== "__main__":