more ui api changes.
[blender.git] / release / scripts / ui / properties_data_modifier.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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20 import bpy
21
22 narrowui = 180
23
24
25 class DataButtonsPanel(bpy.types.Panel):
26     bl_space_type = 'PROPERTIES'
27     bl_region_type = 'WINDOW'
28     bl_context = "modifier"
29
30
31 class DATA_PT_modifiers(DataButtonsPanel):
32     bl_label = "Modifiers"
33
34     def draw(self, context):
35         layout = self.layout
36
37         ob = context.object
38         wide_ui = context.region.width > narrowui
39
40         row = layout.row()
41         row.operator_menu_enum("object.modifier_add", "type")
42         if wide_ui:
43             row.label()
44
45         for md in ob.modifiers:
46             box = layout.template_modifier(md)
47             if box:
48                 # match enum type to our functions, avoids a lookup table.
49                 getattr(self, md.type)(box, ob, md, wide_ui)
50
51     # the mt.type enum is (ab)used for a lookup on function names
52     # ...to avoid lengthy if statements
53     # so each type must have a function here.
54
55     def ARMATURE(self, layout, ob, md, wide_ui):
56         split = layout.split()
57
58         col = split.column()
59         col.label(text="Object:")
60         col.prop(md, "object", text="")
61
62         if wide_ui:
63             col = split.column()
64         col.label(text="Vertex Group::")
65         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
66         sub = col.column()
67         sub.active = bool(md.vertex_group)
68         sub.prop(md, "invert")
69
70         split = layout.split()
71
72         col = split.column()
73         col.label(text="Bind To:")
74         col.prop(md, "use_vertex_groups", text="Vertex Groups")
75         col.prop(md, "use_bone_envelopes", text="Bone Envelopes")
76
77         if wide_ui:
78             col = split.column()
79         col.label(text="Deformation:")
80         col.prop(md, "quaternion")
81         col.prop(md, "multi_modifier")
82
83     def ARRAY(self, layout, ob, md, wide_ui):
84         if wide_ui:
85             layout.prop(md, "fit_type")
86         else:
87             layout.prop(md, "fit_type", text="")
88
89
90         if md.fit_type == 'FIXED_COUNT':
91             layout.prop(md, "count")
92         elif md.fit_type == 'FIT_LENGTH':
93             layout.prop(md, "length")
94         elif md.fit_type == 'FIT_CURVE':
95             layout.prop(md, "curve")
96
97         layout.separator()
98
99         split = layout.split()
100
101         col = split.column()
102         col.prop(md, "constant_offset")
103         sub = col.column()
104         sub.active = md.constant_offset
105         sub.prop(md, "constant_offset_displacement", text="")
106
107         col.separator()
108
109         col.prop(md, "merge_adjacent_vertices", text="Merge")
110         sub = col.column()
111         sub.active = md.merge_adjacent_vertices
112         sub.prop(md, "merge_end_vertices", text="First Last")
113         sub.prop(md, "merge_distance", text="Distance")
114
115         if wide_ui:
116             col = split.column()
117         col.prop(md, "relative_offset")
118         sub = col.column()
119         sub.active = md.relative_offset
120         sub.prop(md, "relative_offset_displacement", text="")
121
122         col.separator()
123
124         col.prop(md, "add_offset_object")
125         sub = col.column()
126         sub.active = md.add_offset_object
127         sub.prop(md, "offset_object", text="")
128
129         layout.separator()
130
131         col = layout.column()
132         col.prop(md, "start_cap")
133         col.prop(md, "end_cap")
134
135     def BEVEL(self, layout, ob, md, wide_ui):
136         split = layout.split()
137
138         col = split.column()
139         col.prop(md, "width")
140
141         if wide_ui:
142             col = split.column()
143         col.prop(md, "only_vertices")
144
145         layout.label(text="Limit Method:")
146         layout.row().prop(md, "limit_method", expand=True)
147         if md.limit_method == 'ANGLE':
148             layout.prop(md, "angle")
149         elif md.limit_method == 'WEIGHT':
150             layout.row().prop(md, "edge_weight_method", expand=True)
151
152     def BOOLEAN(self, layout, ob, md, wide_ui):
153         split = layout.split()
154
155         col = split.column()
156         col.label(text="Operation:")
157         col.prop(md, "operation", text="")
158
159         if wide_ui:
160             col = split.column()
161         col.label(text="Object:")
162         col.prop(md, "object", text="")
163
164     def BUILD(self, layout, ob, md, wide_ui):
165         split = layout.split()
166
167         col = split.column()
168         col.prop(md, "start")
169         col.prop(md, "length")
170
171         if wide_ui:
172             col = split.column()
173         col.prop(md, "randomize")
174         sub = col.column()
175         sub.active = md.randomize
176         sub.prop(md, "seed")
177
178     def CAST(self, layout, ob, md, wide_ui):
179         split = layout.split(percentage=0.25)
180
181         if wide_ui:
182             split.label(text="Cast Type:")
183             split.prop(md, "cast_type", text="")
184         else:
185             layout.prop(md, "cast_type", text="")
186
187         split = layout.split(percentage=0.25)
188
189         col = split.column()
190         col.prop(md, "x")
191         col.prop(md, "y")
192         col.prop(md, "z")
193
194         col = split.column()
195         col.prop(md, "factor")
196         col.prop(md, "radius")
197         col.prop(md, "size")
198         col.prop(md, "from_radius")
199
200         split = layout.split()
201
202         col = split.column()
203         col.label(text="Vertex Group:")
204         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
205         if wide_ui:
206             col = split.column()
207         col.label(text="Control Object:")
208         col.prop(md, "object", text="")
209         if md.object:
210             col.prop(md, "use_transform")
211
212     def CLOTH(self, layout, ob, md, wide_ui):
213         layout.label(text="See Cloth panel.")
214
215     def COLLISION(self, layout, ob, md, wide_ui):
216         layout.label(text="See Collision panel.")
217
218     def CURVE(self, layout, ob, md, wide_ui):
219         split = layout.split()
220
221         col = split.column()
222         col.label(text="Object:")
223         col.prop(md, "object", text="")
224         if wide_ui:
225             col = split.column()
226         col.label(text="Vertex Group:")
227         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
228         layout.label(text="Deformation Axis:")
229         layout.row().prop(md, "deform_axis", expand=True)
230
231     def DECIMATE(self, layout, ob, md, wide_ui):
232         layout.prop(md, "ratio")
233         layout.prop(md, "face_count")
234
235     def DISPLACE(self, layout, ob, md, wide_ui):
236         split = layout.split()
237
238         col = split.column()
239         col.label(text="Texture:")
240         col.prop(md, "texture", text="")
241         col.label(text="Vertex Group:")
242         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
243
244         if wide_ui:
245             col = split.column()
246         col.label(text="Direction:")
247         col.prop(md, "direction", text="")
248         col.label(text="Texture Coordinates:")
249         col.prop(md, "texture_coordinates", text="")
250         if md.texture_coordinates == 'OBJECT':
251             layout.prop(md, "texture_coordinate_object", text="Object")
252         elif md.texture_coordinates == 'UV' and ob.type == 'MESH':
253             layout.prop_object(md, "uv_layer", ob.data, "uv_textures")
254
255         layout.separator()
256
257         split = layout.split()
258
259         col = split.column()
260         col.prop(md, "midlevel")
261
262         if wide_ui:
263             col = split.column()
264         col.prop(md, "strength")
265
266     def EDGE_SPLIT(self, layout, ob, md, wide_ui):
267         split = layout.split()
268
269         col = split.column()
270         col.prop(md, "use_edge_angle", text="Edge Angle")
271         sub = col.column()
272         sub.active = md.use_edge_angle
273         sub.prop(md, "split_angle")
274
275         if wide_ui:
276             col = split.column()
277         col.prop(md, "use_sharp", text="Sharp Edges")
278
279     def EXPLODE(self, layout, ob, md, wide_ui):
280         split = layout.split()
281
282         col = split.column()
283         col.label(text="Vertex group:")
284         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
285         sub = col.column()
286         sub.active = bool(md.vertex_group)
287         sub.prop(md, "protect")
288
289         if wide_ui:
290             col = split.column()
291         col.prop(md, "split_edges")
292         col.prop(md, "unborn")
293         col.prop(md, "alive")
294         col.prop(md, "dead")
295
296         layout.operator("object.explode_refresh", text="Refresh")
297
298     def FLUID_SIMULATION(self, layout, ob, md, wide_ui):
299         layout.label(text="See Fluid panel.")
300
301     def HOOK(self, layout, ob, md, wide_ui):
302         split = layout.split()
303
304         col = split.column()
305         col.label(text="Object:")
306         col.prop(md, "object", text="")
307         if md.object and md.object.type == 'ARMATURE':
308             col.label(text="Bone:")
309             col.prop_object(md, "subtarget", md.object.data, "bones", text="")
310         if wide_ui:
311             col = split.column()
312         col.label(text="Vertex Group:")
313         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
314
315         layout.separator()
316
317         split = layout.split()
318
319         col = split.column()
320         col.prop(md, "falloff")
321         col.prop(md, "force", slider=True)
322         if wide_ui:
323             col = split.column()
324         else:
325             col.separator()
326         col.operator("object.hook_reset", text="Reset")
327         col.operator("object.hook_recenter", text="Recenter")
328
329         if ob.mode == 'EDIT':
330             layout.separator()
331             row = layout.row()
332             row.operator("object.hook_select", text="Select")
333             row.operator("object.hook_assign", text="Assign")
334
335     def LATTICE(self, layout, ob, md, wide_ui):
336         split = layout.split()
337
338         col = split.column()
339         col.label(text="Object:")
340         col.prop(md, "object", text="")
341
342         if wide_ui:
343             col = split.column()
344         col.label(text="Vertex Group:")
345         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
346
347     def MASK(self, layout, ob, md, wide_ui):
348         split = layout.split()
349
350         col = split.column()
351         col.label(text="Mode:")
352         col.prop(md, "mode", text="")
353         if wide_ui:
354             col = split.column()
355         col.label(text="Vertex Group:")
356         if md.mode == 'ARMATURE':
357             col.prop(md, "armature", text="")
358         elif md.mode == 'VERTEX_GROUP':
359             col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
360
361         sub = col.column()
362         sub.active = bool(md.vertex_group)
363         sub.prop(md, "invert")
364
365     def MESH_DEFORM(self, layout, ob, md, wide_ui):
366         split = layout.split()
367         col = split.column()
368         col.label(text="Object:")
369         col.prop(md, "object", text="")
370         if md.object and md.object.type == 'ARMATURE':
371             col.label(text="Bone:")
372             col.prop_object(md, "subtarget", md.object.data, "bones", text="")
373         if wide_ui:
374             col = split.column()
375         col.label(text="Vertex Group:")
376         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
377
378         sub = col.column()
379         sub.active = bool(md.vertex_group)
380         sub.prop(md, "invert")
381
382         layout.separator()
383
384         if md.is_bound:
385             layout.operator("object.meshdeform_bind", text="Unbind")
386         else:
387             layout.operator("object.meshdeform_bind", text="Bind")
388             split = layout.split()
389
390             col = split.column()
391             col.prop(md, "precision")
392
393             if wide_ui:
394                 col = split.column()
395             col.prop(md, "dynamic")
396
397     def MIRROR(self, layout, ob, md, wide_ui):
398         layout.prop(md, "merge_limit")
399         if wide_ui:
400             split = layout.split(percentage=0.25)
401         else:
402             split = layout.split(percentage=0.4)
403
404         col = split.column()
405         col.label(text="Axis:")
406         col.prop(md, "x")
407         col.prop(md, "y")
408         col.prop(md, "z")
409
410         if wide_ui:
411             col = split.column()
412         else:
413             subsplit = layout.split()
414             col = subsplit.column()
415         col.label(text="Options:")
416         col.prop(md, "clip", text="Clipping")
417         col.prop(md, "mirror_vertex_groups", text="Vertex Groups")
418
419         col = split.column()
420         col.label(text="Textures:")
421         col.prop(md, "mirror_u", text="U")
422         col.prop(md, "mirror_v", text="V")
423
424         col = layout.column()
425         col.label(text="Mirror Object:")
426         col.prop(md, "mirror_object", text="")
427
428     def MULTIRES(self, layout, ob, md, wide_ui):
429         if wide_ui:
430             layout.row().prop(md, "subdivision_type", expand=True)
431         else:
432             layout.row().prop(md, "subdivision_type", text="")
433         layout.prop(md, "level")
434
435         split = layout.split()
436
437         col = split.column()
438         col.operator("object.multires_subdivide", text="Subdivide")
439
440         if wide_ui:
441             col = split.column()
442         col.operator("object.multires_higher_levels_delete", text="Delete Higher")
443
444     def PARTICLE_INSTANCE(self, layout, ob, md, wide_ui):
445         layout.prop(md, "object")
446         layout.prop(md, "particle_system_number", text="Particle System")
447
448         split = layout.split()
449         col = split.column()
450         col.label(text="Create From:")
451         col.prop(md, "normal")
452         col.prop(md, "children")
453         col.prop(md, "size")
454
455         if wide_ui:
456             col = split.column()
457         col.label(text="Show Particles When:")
458         col.prop(md, "alive")
459         col.prop(md, "unborn")
460         col.prop(md, "dead")
461
462         layout.separator()
463
464         layout.prop(md, "path", text="Create Along Paths")
465
466         split = layout.split()
467         split.active = md.path
468         col = split.column()
469         col.row().prop(md, "axis", expand=True)
470         col.prop(md, "keep_shape")
471
472         if wide_ui:
473             col = split.column()
474         col.prop(md, "position", slider=True)
475         col.prop(md, "random_position", text="Random", slider=True)
476
477     def PARTICLE_SYSTEM(self, layout, ob, md, wide_ui):
478         layout.label(text="See Particle panel.")
479
480     def SHRINKWRAP(self, layout, ob, md, wide_ui):
481         split = layout.split()
482         col = split.column()
483         col.label(text="Target:")
484         col.prop(md, "target", text="")
485         if wide_ui:
486             col = split.column()
487         col.label(text="Vertex Group:")
488         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
489
490         split = layout.split()
491
492         col = split.column()
493         col.prop(md, "offset")
494         col.prop(md, "subsurf_levels")
495
496         if wide_ui:
497             col = split.column()
498             col.label(text="Mode:")
499         col.prop(md, "mode", text="")
500
501         if wide_ui:
502             split = layout.split(percentage=0.25)
503         else:
504             split = layout.split(percentage=0.35)
505         col = split.column()
506
507         if md.mode == 'PROJECT':
508             col.label(text="Axis:")
509             col.prop(md, "x")
510             col.prop(md, "y")
511             col.prop(md, "z")
512
513             col = split.column()
514             col.label(text="Direction:")
515             col.prop(md, "negative")
516             col.prop(md, "positive")
517
518             if wide_ui:
519                 col = split.column()
520             else:
521                 subsplit = layout.split()
522                 col = subsplit.column()
523             col.label(text="Cull Faces:")
524             col.prop(md, "cull_front_faces", text="Front")
525             col.prop(md, "cull_back_faces", text="Back")
526
527             layout.label(text="Auxiliary Target:")
528             layout.prop(md, "auxiliary_target", text="")
529
530         elif md.mode == 'NEAREST_SURFACEPOINT':
531             layout.prop(md, "keep_above_surface")
532
533     def SIMPLE_DEFORM(self, layout, ob, md, wide_ui):
534         split = layout.split()
535
536         col = split.column()
537         col.label(text="Mode:")
538         col.prop(md, "mode", text="")
539
540         if wide_ui:
541             col = split.column()
542         col.label(text="Vertex Group:")
543         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
544
545         split = layout.split()
546
547         col = split.column()
548         col.label(text="Origin:")
549         col.prop(md, "origin", text="")
550         sub = col.column()
551         sub.active = md.origin
552         sub.prop(md, "relative")
553
554         if wide_ui:
555             col = split.column()
556         col.label(text="Deform:")
557         col.prop(md, "factor")
558         col.prop(md, "limits", slider=True)
559         if md.mode in ('TAPER', 'STRETCH'):
560             col.prop(md, "lock_x_axis")
561             col.prop(md, "lock_y_axis")
562
563     def SMOKE(self, layout, ob, md, wide_ui):
564         layout.label(text="See Smoke panel.")
565
566     def SMOOTH(self, layout, ob, md, wide_ui):
567         split = layout.split(percentage=0.25)
568
569         col = split.column()
570         col.label(text="Axis:")
571         col.prop(md, "x")
572         col.prop(md, "y")
573         col.prop(md, "z")
574
575         col = split.column()
576         col.prop(md, "factor")
577         col.prop(md, "repeat")
578         col.label(text="Vertex Group:")
579         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
580
581     def SOFT_BODY(self, layout, ob, md, wide_ui):
582         layout.label(text="See Soft Body panel.")
583
584     def SUBSURF(self, layout, ob, md, wide_ui):
585         if wide_ui:
586             layout.row().prop(md, "subdivision_type", expand=True)
587         else:
588             layout.row().prop(md, "subdivision_type", text="")
589
590         split = layout.split()
591         col = split.column()
592         col.label(text="Subdivisions:")
593         col.prop(md, "levels", text="View")
594         col.prop(md, "render_levels", text="Render")
595
596         if wide_ui:
597             col = split.column()
598         col.label(text="Options:")
599         col.prop(md, "optimal_draw", text="Optimal Display")
600         col.prop(md, "subsurf_uv")
601
602     def SURFACE(self, layout, ob, md, wide_ui):
603         layout.label(text="See Fields panel.")
604
605     def UV_PROJECT(self, layout, ob, md, wide_ui):
606         if ob.type == 'MESH':
607             split = layout.split()
608             col = split.column()
609             col.label(text="UV Layer:")
610             col.prop_object(md, "uv_layer", ob.data, "uv_textures", text="")
611
612             if wide_ui:
613                 col = split.column()
614             col.label(text="Image:")
615             col.prop(md, "image", text="")
616
617             split = layout.split()
618             col = split.column()
619             col.prop(md, "override_image")
620             col.prop(md, "num_projectors", text="Projectors")
621             for proj in md.projectors:
622                 col.prop(proj, "object", text="")
623
624             if wide_ui:
625                 col = split.column()
626             sub = col.column(align=True)
627             sub.label(text="Aspect Ratio:")
628             sub.prop(md, "horizontal_aspect_ratio", text="Horizontal")
629             sub.prop(md, "vertical_aspect_ratio", text="Vertical")
630
631     def WAVE(self, layout, ob, md, wide_ui):
632         split = layout.split()
633
634         col = split.column()
635         col.label(text="Motion:")
636         col.prop(md, "x")
637         col.prop(md, "y")
638         col.prop(md, "cyclic")
639
640         if wide_ui:
641             col = split.column()
642         col.prop(md, "normals")
643         sub = col.column()
644         sub.active = md.normals
645         sub.prop(md, "x_normal", text="X")
646         sub.prop(md, "y_normal", text="Y")
647         sub.prop(md, "z_normal", text="Z")
648
649         split = layout.split()
650
651         col = split.column()
652         col.label(text="Time:")
653         sub = col.column(align=True)
654         sub.prop(md, "time_offset", text="Offset")
655         sub.prop(md, "lifetime", text="Life")
656         col.prop(md, "damping_time", text="Damping")
657
658         if wide_ui:
659             col = split.column()
660         col.label(text="Position:")
661         sub = col.column(align=True)
662         sub.prop(md, "start_position_x", text="X")
663         sub.prop(md, "start_position_y", text="Y")
664         col.prop(md, "falloff_radius", text="Falloff")
665
666         layout.separator()
667
668         layout.prop(md, "start_position_object")
669         layout.prop_object(md, "vertex_group", ob, "vertex_groups")
670         layout.prop(md, "texture")
671         layout.prop(md, "texture_coordinates")
672         if md.texture_coordinates == 'MAP_UV' and ob.type == 'MESH':
673             layout.prop_object(md, "uv_layer", ob.data, "uv_textures")
674         elif md.texture_coordinates == 'OBJECT':
675             layout.prop(md, "texture_coordinates_object")
676
677         layout.separator()
678
679         split = layout.split()
680
681         col = split.column()
682         col.prop(md, "speed", slider=True)
683         col.prop(md, "height", slider=True)
684
685         if wide_ui:
686             col = split.column()
687         col.prop(md, "width", slider=True)
688         col.prop(md, "narrowness", slider=True)
689
690 bpy.types.register(DATA_PT_modifiers)