change python scripts so modules which register with blender have a register() functi...
[blender.git] / release / scripts / ui / properties_data_mesh.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20 import bpy
21 from rna_prop_ui import PropertyPanel
22
23 narrowui = 180
24
25
26 class MESH_MT_vertex_group_specials(bpy.types.Menu):
27     bl_label = "Vertex Group Specials"
28
29     def draw(self, context):
30         layout = self.layout
31         
32         layout.operator("object.vertex_group_sort", icon='SORTALPHA')
33         layout.operator("object.vertex_group_copy", icon='COPY_ID')
34         layout.operator("object.vertex_group_copy_to_linked", icon='LINK_AREA')
35         layout.operator("object.vertex_group_copy_to_selected", icon='LINK_AREA')
36         layout.operator("object.vertex_group_mirror", icon='ARROW_LEFTRIGHT')
37
38
39 class MESH_MT_shape_key_specials(bpy.types.Menu):
40     bl_label = "Shape Key Specials"
41
42     def draw(self, context):
43         layout = self.layout
44
45         layout.operator("object.shape_key_transfer", icon='COPY_ID') # icon is not ideal
46         layout.operator("object.join_shapes", icon='COPY_ID') # icon is not ideal
47         layout.operator("object.shape_key_mirror", icon='ARROW_LEFTRIGHT')
48
49
50 class DataButtonsPanel(bpy.types.Panel):
51     bl_space_type = 'PROPERTIES'
52     bl_region_type = 'WINDOW'
53     bl_context = "data"
54
55     def poll(self, context):
56         return context.mesh
57
58
59 class DATA_PT_context_mesh(DataButtonsPanel):
60     bl_label = ""
61     bl_show_header = False
62
63     def draw(self, context):
64         layout = self.layout
65
66         ob = context.object
67         mesh = context.mesh
68         space = context.space_data
69         wide_ui = context.region.width > narrowui
70
71         if wide_ui:
72             split = layout.split(percentage=0.65)
73             if ob:
74                 split.template_ID(ob, "data")
75                 split.separator()
76             elif mesh:
77                 split.template_ID(space, "pin_id")
78                 split.separator()
79         else:
80             if ob:
81                 layout.template_ID(ob, "data")
82             elif mesh:
83                 layout.template_ID(space, "pin_id")
84
85
86 class DATA_PT_custom_props_mesh(DataButtonsPanel, PropertyPanel):
87     _context_path = "object.data"
88
89
90 class DATA_PT_normals(DataButtonsPanel):
91     bl_label = "Normals"
92
93     def draw(self, context):
94         layout = self.layout
95
96         mesh = context.mesh
97         wide_ui = context.region.width > narrowui
98
99         split = layout.split()
100
101         col = split.column()
102         col.prop(mesh, "autosmooth")
103         sub = col.column()
104         sub.active = mesh.autosmooth
105         sub.prop(mesh, "autosmooth_angle", text="Angle")
106
107         if wide_ui:
108             col = split.column()
109         else:
110             col.separator()
111         col.prop(mesh, "vertex_normal_flip")
112         col.prop(mesh, "double_sided")
113
114
115 class DATA_PT_settings(DataButtonsPanel):
116     bl_label = "Settings"
117
118     def draw(self, context):
119         layout = self.layout
120
121         mesh = context.mesh
122
123         layout.prop(mesh, "texture_mesh")
124
125
126 class DATA_PT_vertex_groups(DataButtonsPanel):
127     bl_label = "Vertex Groups"
128
129     def poll(self, context):
130         return (context.object and context.object.type in ('MESH', 'LATTICE'))
131
132     def draw(self, context):
133         layout = self.layout
134
135         ob = context.object
136         group = ob.active_vertex_group
137
138         rows = 2
139         if group:
140             rows = 5
141
142         row = layout.row()
143         row.template_list(ob, "vertex_groups", ob, "active_vertex_group_index", rows=rows)
144
145         col = row.column(align=True)
146         col.operator("object.vertex_group_add", icon='ZOOMIN', text="")
147         col.operator("object.vertex_group_remove", icon='ZOOMOUT', text="")
148         col.menu("MESH_MT_vertex_group_specials", icon='DOWNARROW_HLT', text="")
149
150         if group:
151             row = layout.row()
152             row.prop(group, "name")
153
154         if ob.mode == 'EDIT' and len(ob.vertex_groups) > 0:
155             row = layout.row()
156
157             sub = row.row(align=True)
158             sub.operator("object.vertex_group_assign", text="Assign")
159             sub.operator("object.vertex_group_remove_from", text="Remove")
160
161             sub = row.row(align=True)
162             sub.operator("object.vertex_group_select", text="Select")
163             sub.operator("object.vertex_group_deselect", text="Deselect")
164
165             layout.prop(context.tool_settings, "vertex_group_weight", text="Weight")
166
167
168 class DATA_PT_shape_keys(DataButtonsPanel):
169     bl_label = "Shape Keys"
170
171     def poll(self, context):
172         return (context.object and context.object.type in ('MESH', 'LATTICE', 'CURVE', 'SURFACE'))
173
174     def draw(self, context):
175         layout = self.layout
176
177         ob = context.object
178         key = ob.data.shape_keys
179         kb = ob.active_shape_key
180         wide_ui = context.region.width > narrowui
181
182         enable_edit = ob.mode != 'EDIT'
183         enable_edit_value = False
184
185         if ob.shape_key_lock is False:
186             if enable_edit or (ob.type == 'MESH' and ob.shape_key_edit_mode):
187                 enable_edit_value = True
188
189         row = layout.row()
190
191         rows = 2
192         if kb:
193             rows = 5
194         row.template_list(key, "keys", ob, "active_shape_key_index", rows=rows)
195
196         col = row.column()
197
198         sub = col.column(align=True)
199         sub.operator("object.shape_key_add", icon='ZOOMIN', text="")
200         sub.operator("object.shape_key_remove", icon='ZOOMOUT', text="")
201         sub.menu("MESH_MT_shape_key_specials", icon='DOWNARROW_HLT', text="")
202
203         if kb:
204             col.separator()
205
206             sub = col.column(align=True)
207             sub.operator("object.shape_key_move", icon='TRIA_UP', text="").type = 'UP'
208             sub.operator("object.shape_key_move", icon='TRIA_DOWN', text="").type = 'DOWN'
209
210             split = layout.split(percentage=0.4)
211             row = split.row()
212             row.enabled = enable_edit
213             if wide_ui:
214                 row.prop(key, "relative")
215
216             row = split.row()
217             row.alignment = 'RIGHT'
218
219             if not wide_ui:
220                 layout.prop(key, "relative")
221                 row = layout.row()
222
223
224             sub = row.row(align=True)
225             subsub = sub.row(align=True)
226             subsub.active = enable_edit_value
227             subsub.prop(ob, "shape_key_lock", text="")
228             subsub.prop(kb, "mute", text="")
229             sub.prop(ob, "shape_key_edit_mode", text="")
230             
231             sub = row.row()
232             sub.operator("object.shape_key_clear", icon='X', text="")
233
234             row = layout.row()
235             row.prop(kb, "name")
236
237             if key.relative:
238                 if ob.active_shape_key_index != 0:
239                     row = layout.row()
240                     row.active = enable_edit_value
241                     row.prop(kb, "value")
242
243                     split = layout.split()
244
245                     col = split.column(align=True)
246                     col.active = enable_edit_value
247                     col.label(text="Range:")
248                     col.prop(kb, "slider_min", text="Min")
249                     col.prop(kb, "slider_max", text="Max")
250
251                     if wide_ui:
252                         col = split.column(align=True)
253                     col.active = enable_edit_value
254                     col.label(text="Blend:")
255                     col.prop_object(kb, "vertex_group", ob, "vertex_groups", text="")
256                     col.prop_object(kb, "relative_key", key, "keys", text="")
257
258             else:
259                 row = layout.row()
260                 row.active = enable_edit_value
261                 row.prop(key, "slurph")
262
263
264 class DATA_PT_uv_texture(DataButtonsPanel):
265     bl_label = "UV Texture"
266
267     def draw(self, context):
268         layout = self.layout
269
270         me = context.mesh
271
272         row = layout.row()
273         col = row.column()
274
275         col.template_list(me, "uv_textures", me, "active_uv_texture_index", rows=2)
276
277         col = row.column(align=True)
278         col.operator("mesh.uv_texture_add", icon='ZOOMIN', text="")
279         col.operator("mesh.uv_texture_remove", icon='ZOOMOUT', text="")
280
281         lay = me.active_uv_texture
282         if lay:
283             layout.prop(lay, "name")
284
285
286 class DATA_PT_vertex_colors(DataButtonsPanel):
287     bl_label = "Vertex Colors"
288
289     def draw(self, context):
290         layout = self.layout
291
292         me = context.mesh
293
294         row = layout.row()
295         col = row.column()
296
297         col.template_list(me, "vertex_colors", me, "active_vertex_color_index", rows=2)
298
299         col = row.column(align=True)
300         col.operator("mesh.vertex_color_add", icon='ZOOMIN', text="")
301         col.operator("mesh.vertex_color_remove", icon='ZOOMOUT', text="")
302
303         lay = me.active_vertex_color
304         if lay:
305             layout.prop(lay, "name")
306
307
308 classes = [
309     MESH_MT_vertex_group_specials,
310     MESH_MT_shape_key_specials,
311
312     DATA_PT_context_mesh,
313     DATA_PT_normals,
314     DATA_PT_settings,
315     DATA_PT_vertex_groups,
316     DATA_PT_shape_keys,
317     DATA_PT_uv_texture,
318     DATA_PT_vertex_colors,
319
320     DATA_PT_custom_props_mesh]
321
322
323 def register():
324     register = bpy.types.register
325     for cls in classes:
326         register(cls)
327
328 def unregister():
329     unregister = bpy.types.unregister
330     for cls in classes:
331         unregister(cls)