Update for 2.8
[blender-addons.git] / mesh_extra_tools / vertex_align.py
blobe5570fd1fbde9aa783d20e1286cf61bcd4dc4cba
1 # -*- coding: utf-8 -*-
3 # ##### BEGIN GPL LICENSE BLOCK #####
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software Foundation,
17 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 # ##### END GPL LICENSE BLOCK #####
21 # Note: Property group was moved to __init__
23 bl_info = {
24 "name": "Vertex Align",
25 "author": "",
26 "version": (0, 1, 7),
27 "blender": (2, 6, 1),
28 "location": "View3D > Tool Shelf",
29 "description": "",
30 "warning": "",
31 "wiki_url": "",
32 "category": "Mesh"}
35 import bpy
36 from bpy.props import (
37 BoolVectorProperty,
38 FloatVectorProperty,
40 from mathutils import Vector
41 from bpy.types import Operator
44 # Edit Mode Toggle
45 def edit_mode_out():
46 bpy.ops.object.mode_set(mode='OBJECT')
49 def edit_mode_in():
50 bpy.ops.object.mode_set(mode='EDIT')
53 def get_mesh_data_():
54 edit_mode_out()
55 ob_act = bpy.context.active_object
56 me = ob_act.data
57 edit_mode_in()
58 return me
61 def list_clear_(l):
62 l[:] = []
63 return l
66 class va_buf():
67 list_v = []
68 list_0 = []
71 # Store The Vertex coordinates
72 class Vertex_align_store(Operator):
73 bl_idname = "vertex_align.store_id"
74 bl_label = "Active Vertex"
75 bl_description = ("Store Selected Vertex coordinates as an align point\n"
76 "Single Selected Vertex only")
78 @classmethod
79 def poll(cls, context):
80 obj = context.active_object
81 return (obj and obj.type == 'MESH' and context.mode == 'EDIT_MESH')
83 def execute(self, context):
84 try:
85 me = get_mesh_data_()
86 list_0 = [v.index for v in me.vertices if v.select]
88 if len(list_0) == 1:
89 list_clear_(va_buf.list_v)
90 for v in me.vertices:
91 if v.select:
92 va_buf.list_v.append(v.index)
93 bpy.ops.mesh.select_all(action='DESELECT')
94 else:
95 self.report({'WARNING'}, "Please select just One Vertex")
96 return {'CANCELLED'}
97 except:
98 self.report({'WARNING'}, "Storing selection could not be completed")
99 return {'CANCELLED'}
101 self.report({'INFO'}, "Selected Vertex coordinates are stored")
103 return {'FINISHED'}
106 # Align to original
107 class Vertex_align_original(Operator):
108 bl_idname = "vertex_align.align_original"
109 bl_label = "Align to original"
110 bl_description = "Align selection to stored single vertex coordinates"
111 bl_options = {'REGISTER', 'UNDO'}
113 @classmethod
114 def poll(cls, context):
115 obj = context.active_object
116 return (obj and obj.type == 'MESH' and context.mode == 'EDIT_MESH')
118 def draw(self, context):
119 layout = self.layout
120 layout.label("Axis:")
122 row = layout.row(align=True)
123 row.prop(context.scene.mesh_extra_tools, "vert_align_axis",
124 text="X", index=0, toggle=True)
125 row.prop(context.scene.mesh_extra_tools, "vert_align_axis",
126 text="Y", index=1, toggle=True)
127 row.prop(context.scene.mesh_extra_tools, "vert_align_axis",
128 text="Z", index=2, toggle=True)
130 def execute(self, context):
131 edit_mode_out()
132 ob_act = context.active_object
133 me = ob_act.data
134 cen1 = context.scene.mesh_extra_tools.vert_align_axis
135 list_0 = [v.index for v in me.vertices if v.select]
137 if len(va_buf.list_v) == 0:
138 self.report({'INFO'},
139 "Original vertex not stored in memory. Operation Cancelled")
140 edit_mode_in()
141 return {'CANCELLED'}
143 elif len(va_buf.list_v) != 0:
144 if len(list_0) == 0:
145 self.report({'INFO'}, "No vertices selected. Operation Cancelled")
146 edit_mode_in()
147 return {'CANCELLED'}
149 elif len(list_0) != 0:
150 vo = (me.vertices[va_buf.list_v[0]].co).copy()
151 if cen1[0] is True:
152 for i in list_0:
153 v = (me.vertices[i].co).copy()
154 me.vertices[i].co = Vector((vo[0], v[1], v[2]))
155 if cen1[1] is True:
156 for i in list_0:
157 v = (me.vertices[i].co).copy()
158 me.vertices[i].co = Vector((v[0], vo[1], v[2]))
159 if cen1[2] is True:
160 for i in list_0:
161 v = (me.vertices[i].co).copy()
162 me.vertices[i].co = Vector((v[0], v[1], vo[2]))
163 edit_mode_in()
165 return {'FINISHED'}
168 # Align to custom coordinates
169 class Vertex_align_coord_list(Operator):
170 bl_idname = "vertex_align.coord_list_id"
171 bl_label = ""
172 bl_description = "Align to custom coordinates"
174 @classmethod
175 def poll(cls, context):
176 obj = context.active_object
177 return (obj and obj.type == 'MESH' and context.mode == 'EDIT_MESH')
179 def execute(self, context):
180 edit_mode_out()
181 ob_act = context.active_object
182 me = ob_act.data
183 list_clear_(va_buf.list_0)
184 va_buf.list_0 = [v.index for v in me.vertices if v.select][:]
186 if len(va_buf.list_0) == 0:
187 self.report({'INFO'}, "No vertices selected. Operation Cancelled")
188 edit_mode_in()
189 return {'CANCELLED'}
191 elif len(va_buf.list_0) != 0:
192 bpy.ops.vertex_align.coord_menu_id('INVOKE_DEFAULT')
194 edit_mode_in()
196 return {'FINISHED'}
199 # Align to custom coordinates menu
200 class Vertex_align_coord_menu(Operator):
201 bl_idname = "vertex_align.coord_menu_id"
202 bl_label = "Tweak custom coordinates"
203 bl_description = "Change the custom coordinates for aligning"
204 bl_options = {'REGISTER', 'UNDO'}
206 def_axis_coord = FloatVectorProperty(
207 name="",
208 description="Enter the values of coordinates",
209 default=(0.0, 0.0, 0.0),
210 min=-100.0, max=100.0,
211 step=1, size=3,
212 subtype='XYZ',
213 precision=3
215 use_axis_coord = BoolVectorProperty(
216 name="Axis",
217 description="Choose Custom Coordinates axis",
218 default=(False,) * 3,
219 size=3,
221 is_not_undo = False
223 @classmethod
224 def poll(cls, context):
225 obj = context.active_object
226 return (obj and obj.type == 'MESH')
228 def using_store(self, context):
229 scene = context.scene
230 return scene.mesh_extra_tools.vert_align_use_stored
232 def draw(self, context):
233 layout = self.layout
235 if self.using_store(context) and self.is_not_undo:
236 layout.label("Using Stored Coordinates", icon="INFO")
238 row = layout.split(0.25)
239 row.prop(self, "use_axis_coord", index=0, text="X")
240 row.prop(self, "def_axis_coord", index=0)
242 row = layout.split(0.25)
243 row.prop(self, "use_axis_coord", index=1, text="Y")
244 row.prop(self, "def_axis_coord", index=1)
246 row = layout.split(0.25)
247 row.prop(self, "use_axis_coord", index=2, text="Z")
248 row.prop(self, "def_axis_coord", index=2)
250 def invoke(self, context, event):
251 self.is_not_undo = True
252 scene = context.scene
253 if self.using_store(context):
254 self.def_axis_coord = scene.mesh_extra_tools.vert_align_store_axis
256 return context.window_manager.invoke_props_dialog(self, width=200)
258 def execute(self, context):
259 self.is_not_undo = False
260 edit_mode_out()
261 ob_act = context.active_object
262 me = ob_act.data
264 for i in va_buf.list_0:
265 v = (me.vertices[i].co).copy()
266 tmp = Vector((v[0], v[1], v[2]))
268 if self.use_axis_coord[0] is True:
269 tmp[0] = self.def_axis_coord[0]
270 if self.use_axis_coord[1] is True:
271 tmp[1] = self.def_axis_coord[1]
272 if self.use_axis_coord[2] is True:
273 tmp[2] = self.def_axis_coord[2]
274 me.vertices[i].co = tmp
276 edit_mode_in()
278 return {'FINISHED'}
281 # Register
282 classes = (
283 Vertex_align_store,
284 Vertex_align_original,
285 Vertex_align_coord_list,
286 Vertex_align_coord_menu,
290 def register():
291 for cls in classes:
292 bpy.utils.register_class(cls)
295 def unregister():
296 for cls in classes:
297 bpy.utils.unregister_class(cls)
300 if __name__ == "__main__":
301 register()