poll() as a python '@staticmethod' was too limiting and didnt allow useful base class...
[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
24 class MESH_MT_vertex_group_specials(bpy.types.Menu):
25     bl_label = "Vertex Group Specials"
26     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
27
28     def draw(self, context):
29         layout = self.layout
30
31         layout.operator("object.vertex_group_sort", icon='SORTALPHA')
32         layout.operator("object.vertex_group_copy", icon='COPY_ID')
33         layout.operator("object.vertex_group_copy_to_linked", icon='LINK_AREA')
34         layout.operator("object.vertex_group_copy_to_selected", icon='LINK_AREA')
35         layout.operator("object.vertex_group_mirror", icon='ARROW_LEFTRIGHT')
36
37
38 class MESH_MT_shape_key_specials(bpy.types.Menu):
39     bl_label = "Shape Key Specials"
40     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
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 MeshButtonsPanel():
51     bl_space_type = 'PROPERTIES'
52     bl_region_type = 'WINDOW'
53     bl_context = "data"
54
55     @classmethod
56     def poll(cls, context):
57         engine = context.scene.render.engine
58         return context.mesh and (engine in cls.COMPAT_ENGINES)
59
60
61 class DATA_PT_context_mesh(MeshButtonsPanel, bpy.types.Panel):
62     bl_label = ""
63     bl_show_header = False
64     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
65
66     def draw(self, context):
67         layout = self.layout
68
69         ob = context.object
70         mesh = context.mesh
71         space = context.space_data
72
73         split = layout.split(percentage=0.65)
74         if ob:
75             split.template_ID(ob, "data")
76             split.separator()
77         elif mesh:
78             split.template_ID(space, "pin_id")
79             split.separator()
80
81
82 class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, bpy.types.Panel):
83     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
84     _context_path = "object.data"
85
86
87 class DATA_PT_normals(MeshButtonsPanel, bpy.types.Panel):
88     bl_label = "Normals"
89     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
90
91     def draw(self, context):
92         layout = self.layout
93
94         mesh = context.mesh
95
96         split = layout.split()
97
98         col = split.column()
99         col.prop(mesh, "autosmooth")
100         sub = col.column()
101         sub.active = mesh.autosmooth
102         sub.prop(mesh, "autosmooth_angle", text="Angle")
103
104         col = split.column()
105
106         col.prop(mesh, "double_sided")
107
108
109 class DATA_PT_settings(MeshButtonsPanel, bpy.types.Panel):
110     bl_label = "Settings"
111     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
112
113     def draw(self, context):
114         layout = self.layout
115
116         mesh = context.mesh
117
118         layout.prop(mesh, "texture_mesh")
119
120
121 class DATA_PT_vertex_groups(MeshButtonsPanel, bpy.types.Panel):
122     bl_label = "Vertex Groups"
123     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
124
125     @classmethod
126     def poll(cls, context):
127         engine = context.scene.render.engine
128         obj = context.object
129         return (obj and obj.type in ('MESH', 'LATTICE') and (engine in cls.COMPAT_ENGINES))
130
131     def draw(self, context):
132         layout = self.layout
133
134         ob = context.object
135         group = ob.active_vertex_group
136
137         rows = 2
138         if group:
139             rows = 5
140
141         row = layout.row()
142         row.template_list(ob, "vertex_groups", ob, "active_vertex_group_index", rows=rows)
143
144         col = row.column(align=True)
145         col.operator("object.vertex_group_add", icon='ZOOMIN', text="")
146         col.operator("object.vertex_group_remove", icon='ZOOMOUT', text="")
147         col.menu("MESH_MT_vertex_group_specials", icon='DOWNARROW_HLT', text="")
148         if group:
149             col.operator("object.vertex_group_move", icon='TRIA_UP', text="").direction = 'UP'
150             col.operator("object.vertex_group_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
151
152         if group:
153             row = layout.row()
154             row.prop(group, "name")
155
156         if ob.mode == 'EDIT' and len(ob.vertex_groups) > 0:
157             row = layout.row()
158
159             sub = row.row(align=True)
160             sub.operator("object.vertex_group_assign", text="Assign")
161             sub.operator("object.vertex_group_remove_from", text="Remove")
162
163             sub = row.row(align=True)
164             sub.operator("object.vertex_group_select", text="Select")
165             sub.operator("object.vertex_group_deselect", text="Deselect")
166
167             layout.prop(context.tool_settings, "vertex_group_weight", text="Weight")
168
169
170 class DATA_PT_shape_keys(MeshButtonsPanel, bpy.types.Panel):
171     bl_label = "Shape Keys"
172     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
173
174     @classmethod
175     def poll(cls, context):
176         engine = context.scene.render.engine
177         obj = context.object
178         return (obj and obj.type in ('MESH', 'LATTICE', 'CURVE', 'SURFACE') and (engine in cls.COMPAT_ENGINES))
179
180     def draw(self, context):
181         layout = self.layout
182
183         ob = context.object
184         key = ob.data.shape_keys
185         kb = ob.active_shape_key
186
187         enable_edit = ob.mode != 'EDIT'
188         enable_edit_value = False
189
190         if ob.shape_key_lock is False:
191             if enable_edit or (ob.type == 'MESH' and ob.shape_key_edit_mode):
192                 enable_edit_value = True
193
194         row = layout.row()
195
196         rows = 2
197         if kb:
198             rows = 5
199         row.template_list(key, "keys", ob, "active_shape_key_index", rows=rows)
200
201         col = row.column()
202
203         sub = col.column(align=True)
204         sub.operator("object.shape_key_add", icon='ZOOMIN', text="")
205         sub.operator("object.shape_key_remove", icon='ZOOMOUT', text="")
206         sub.menu("MESH_MT_shape_key_specials", icon='DOWNARROW_HLT', text="")
207
208         if kb:
209             col.separator()
210
211             sub = col.column(align=True)
212             sub.operator("object.shape_key_move", icon='TRIA_UP', text="").type = 'UP'
213             sub.operator("object.shape_key_move", icon='TRIA_DOWN', text="").type = 'DOWN'
214
215             split = layout.split(percentage=0.4)
216             row = split.row()
217             row.enabled = enable_edit
218             row.prop(key, "relative")
219
220             row = split.row()
221             row.alignment = 'RIGHT'
222
223             sub = row.row(align=True)
224             subsub = sub.row(align=True)
225             subsub.active = enable_edit_value
226             subsub.prop(ob, "shape_key_lock", text="")
227             subsub.prop(kb, "mute", text="")
228             sub.prop(ob, "shape_key_edit_mode", text="")
229
230             sub = row.row()
231             sub.operator("object.shape_key_clear", icon='X', text="")
232
233             row = layout.row()
234             row.prop(kb, "name")
235
236             if key.relative:
237                 if ob.active_shape_key_index != 0:
238                     row = layout.row()
239                     row.active = enable_edit_value
240                     row.prop(kb, "value")
241
242                     split = layout.split()
243
244                     col = split.column(align=True)
245                     col.active = enable_edit_value
246                     col.label(text="Range:")
247                     col.prop(kb, "slider_min", text="Min")
248                     col.prop(kb, "slider_max", text="Max")
249
250                     col = split.column(align=True)
251                     col.active = enable_edit_value
252                     col.label(text="Blend:")
253                     col.prop_object(kb, "vertex_group", ob, "vertex_groups", text="")
254                     col.prop_object(kb, "relative_key", key, "keys", text="")
255
256             else:
257                 row = layout.row()
258                 row.active = enable_edit_value
259                 row.prop(key, "slurph")
260
261
262 class DATA_PT_uv_texture(MeshButtonsPanel, bpy.types.Panel):
263     bl_label = "UV Texture"
264     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
265
266     def draw(self, context):
267         layout = self.layout
268
269         me = context.mesh
270
271         row = layout.row()
272         col = row.column()
273
274         col.template_list(me, "uv_textures", me, "active_uv_texture_index", rows=2)
275
276         col = row.column(align=True)
277         col.operator("mesh.uv_texture_add", icon='ZOOMIN', text="")
278         col.operator("mesh.uv_texture_remove", icon='ZOOMOUT', text="")
279
280         lay = me.active_uv_texture
281         if lay:
282             layout.prop(lay, "name")
283
284
285 class DATA_PT_texface(MeshButtonsPanel, bpy.types.Panel):
286     bl_label = "Texture Face"
287     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
288
289     @classmethod
290     def poll(cls, context):
291         ob = context.active_object
292         rd = context.scene.render
293
294         return (context.mode == 'EDIT_MESH') and (rd.engine == 'BLENDER_GAME') and ob and ob.type == 'MESH'
295
296     def draw(self, context):
297         layout = self.layout
298         col = layout.column()
299
300         me = context.mesh
301
302         tf = me.faces.active_tface
303
304         if tf:
305             split = layout.split()
306             col = split.column()
307
308             col.prop(tf, "tex")
309             col.prop(tf, "light")
310             col.prop(tf, "invisible")
311             col.prop(tf, "collision")
312
313             col.prop(tf, "shared")
314             col.prop(tf, "twoside")
315             col.prop(tf, "object_color")
316
317             col = split.column()
318
319             col.prop(tf, "halo")
320             col.prop(tf, "billboard")
321             col.prop(tf, "shadow")
322             col.prop(tf, "text")
323             col.prop(tf, "alpha_sort")
324
325             col = layout.column()
326             col.prop(tf, "transp")
327         else:
328             col.label(text="No UV Texture")
329
330
331 class DATA_PT_vertex_colors(MeshButtonsPanel, bpy.types.Panel):
332     bl_label = "Vertex Colors"
333     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
334
335     def draw(self, context):
336         layout = self.layout
337
338         me = context.mesh
339
340         row = layout.row()
341         col = row.column()
342
343         col.template_list(me, "vertex_colors", me, "active_vertex_color_index", rows=2)
344
345         col = row.column(align=True)
346         col.operator("mesh.vertex_color_add", icon='ZOOMIN', text="")
347         col.operator("mesh.vertex_color_remove", icon='ZOOMOUT', text="")
348
349         lay = me.active_vertex_color
350         if lay:
351             layout.prop(lay, "name")
352
353
354 def register():
355     pass
356
357
358 def unregister():
359     pass
360
361 if __name__ == "__main__":
362     register()