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