svn merge ^/trunk/blender -r43009:43033
[blender.git] / release / scripts / startup / bl_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., 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 bpy.types import Panel
22
23
24 class ModifierButtonsPanel():
25     bl_space_type = 'PROPERTIES'
26     bl_region_type = 'WINDOW'
27     bl_context = "modifier"
28
29
30 class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
31     bl_label = "Modifiers"
32
33     def draw(self, context):
34         layout = self.layout
35
36         ob = context.object
37
38         layout.operator_menu_enum("object.modifier_add", "type")
39
40         for md in ob.modifiers:
41             box = layout.template_modifier(md)
42             if box:
43                 # match enum type to our functions, avoids a lookup table.
44                 getattr(self, md.type)(box, ob, md)
45
46     # the mt.type enum is (ab)used for a lookup on function names
47     # ...to avoid lengthy if statements
48     # so each type must have a function here.
49         
50     def NGONINTERP(self, layout, ob, md):
51         split = layout.split()
52         split.prop(md, "resolution")
53         
54     def ARMATURE(self, layout, ob, md):
55         split = layout.split()
56
57         col = split.column()
58         col.label(text="Object:")
59         col.prop(md, "object", text="")
60         col.prop(md, "use_deform_preserve_volume")
61
62         col = split.column()
63         col.label(text="Bind To:")
64         col.prop(md, "use_vertex_groups", text="Vertex Groups")
65         col.prop(md, "use_bone_envelopes", text="Bone Envelopes")
66
67         layout.separator()
68
69         row = layout.row()
70         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
71         sub = row.row()
72         sub.active = bool(md.vertex_group)
73         sub.prop(md, "invert_vertex_group")
74
75         layout.prop(md, "use_multi_modifier")
76
77     def ARRAY(self, layout, ob, md):
78         layout.prop(md, "fit_type")
79
80         if md.fit_type == 'FIXED_COUNT':
81             layout.prop(md, "count")
82         elif md.fit_type == 'FIT_LENGTH':
83             layout.prop(md, "fit_length")
84         elif md.fit_type == 'FIT_CURVE':
85             layout.prop(md, "curve")
86
87         layout.separator()
88
89         split = layout.split()
90
91         col = split.column()
92         col.prop(md, "use_constant_offset")
93         sub = col.column()
94         sub.active = md.use_constant_offset
95         sub.prop(md, "constant_offset_displace", text="")
96
97         col.separator()
98
99         col.prop(md, "use_merge_vertices", text="Merge")
100         sub = col.column()
101         sub.active = md.use_merge_vertices
102         sub.prop(md, "use_merge_vertices_cap", text="First Last")
103         sub.prop(md, "merge_threshold", text="Distance")
104
105         col = split.column()
106         col.prop(md, "use_relative_offset")
107         sub = col.column()
108         sub.active = md.use_relative_offset
109         sub.prop(md, "relative_offset_displace", text="")
110
111         col.separator()
112
113         col.prop(md, "use_object_offset")
114         sub = col.column()
115         sub.active = md.use_object_offset
116         sub.prop(md, "offset_object", text="")
117
118         layout.separator()
119
120         layout.prop(md, "start_cap")
121         layout.prop(md, "end_cap")
122
123     def BEVEL(self, layout, ob, md):
124         split = layout.split()
125
126         split.prop(md, "width")
127         split.prop(md, "use_only_vertices")
128
129         # BMESH_BRANCH ONLY
130         split = layout.split()
131         split.prop(md, "use_even_offset")
132         split.prop(md, "use_distance_offset")
133         # END BMESH_BRANCH ONLY
134
135         layout.label(text="Limit Method:")
136         layout.row().prop(md, "limit_method", expand=True)
137         if md.limit_method == 'ANGLE':
138             layout.prop(md, "angle_limit")
139         elif md.limit_method == 'WEIGHT':
140             layout.row().prop(md, "edge_weight_method", expand=True)
141
142     def BOOLEAN(self, layout, ob, md):
143         split = layout.split()
144
145         col = split.column()
146         col.label(text="Operation:")
147         col.prop(md, "operation", text="")
148
149         col = split.column()
150         col.label(text="Object:")
151         col.prop(md, "object", text="")
152
153     def BUILD(self, layout, ob, md):
154         split = layout.split()
155
156         col = split.column()
157         col.prop(md, "frame_start")
158         col.prop(md, "frame_duration")
159
160         col = split.column()
161         col.prop(md, "use_random_order")
162         sub = col.column()
163         sub.active = md.use_random_order
164         sub.prop(md, "seed")
165
166     def CAST(self, layout, ob, md):
167         split = layout.split(percentage=0.25)
168
169         split.label(text="Cast Type:")
170         split.prop(md, "cast_type", text="")
171
172         split = layout.split(percentage=0.25)
173
174         col = split.column()
175         col.prop(md, "use_x")
176         col.prop(md, "use_y")
177         col.prop(md, "use_z")
178
179         col = split.column()
180         col.prop(md, "factor")
181         col.prop(md, "radius")
182         col.prop(md, "size")
183         col.prop(md, "use_radius_as_size")
184
185         split = layout.split()
186
187         col = split.column()
188         col.label(text="Vertex Group:")
189         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
190         col = split.column()
191         col.label(text="Control Object:")
192         col.prop(md, "object", text="")
193         if md.object:
194             col.prop(md, "use_transform")
195
196     def CLOTH(self, layout, ob, md):
197         layout.label(text="Settings can be found inside the Physics context")
198
199     def COLLISION(self, layout, ob, md):
200         layout.label(text="Settings can be found inside the Physics context")
201
202     def CURVE(self, layout, ob, md):
203         split = layout.split()
204
205         col = split.column()
206         col.label(text="Object:")
207         col.prop(md, "object", text="")
208         col = split.column()
209         col.label(text="Vertex Group:")
210         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
211         layout.label(text="Deformation Axis:")
212         layout.row().prop(md, "deform_axis", expand=True)
213
214     def DECIMATE(self, layout, ob, md):
215         layout.prop(md, "ratio")
216         layout.label(text="Face Count" + ": %d" % md.face_count)
217
218     def DISPLACE(self, layout, ob, md):
219         split = layout.split()
220
221         col = split.column()
222         col.label(text="Texture:")
223         col.template_ID(md, "texture", new="texture.new")
224         col.label(text="Vertex Group:")
225         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
226
227         col = split.column()
228         col.label(text="Direction:")
229         col.prop(md, "direction", text="")
230         col.label(text="Texture Coordinates:")
231         col.prop(md, "texture_coords", text="")
232         if md.texture_coords == 'OBJECT':
233             layout.prop(md, "texture_coords_object", text="Object")
234         elif md.texture_coords == 'UV' and ob.type == 'MESH':
235             layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
236
237         layout.separator()
238
239         row = layout.row()
240         row.prop(md, "mid_level")
241         row.prop(md, "strength")
242
243     def DYNAMIC_PAINT(self, layout, ob, md):
244         layout.label(text="Settings can be found inside the Physics context")
245
246     def EDGE_SPLIT(self, layout, ob, md):
247         split = layout.split()
248
249         col = split.column()
250         col.prop(md, "use_edge_angle", text="Edge Angle")
251         sub = col.column()
252         sub.active = md.use_edge_angle
253         sub.prop(md, "split_angle")
254
255         split.prop(md, "use_edge_sharp", text="Sharp Edges")
256
257     def EXPLODE(self, layout, ob, md):
258         split = layout.split()
259
260         col = split.column()
261         col.label(text="Vertex group:")
262         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
263         sub = col.column()
264         sub.active = bool(md.vertex_group)
265         sub.prop(md, "protect")
266         col.label(text="Particle UV")
267         col.prop_search(md, "particle_uv", ob.data, "uv_textures", text="")
268
269         col = split.column()
270         col.prop(md, "use_edge_cut")
271         col.prop(md, "show_unborn")
272         col.prop(md, "show_alive")
273         col.prop(md, "show_dead")
274         col.prop(md, "use_size")
275
276         layout.operator("object.explode_refresh", text="Refresh")
277
278     def FLUID_SIMULATION(self, layout, ob, md):
279         layout.label(text="Settings can be found inside the Physics context")
280
281     def HOOK(self, layout, ob, md):
282         split = layout.split()
283
284         col = split.column()
285         col.label(text="Object:")
286         col.prop(md, "object", text="")
287         if md.object and md.object.type == 'ARMATURE':
288             col.label(text="Bone:")
289             col.prop_search(md, "subtarget", md.object.data, "bones", text="")
290         col = split.column()
291         col.label(text="Vertex Group:")
292         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
293
294         layout.separator()
295
296         split = layout.split()
297
298         col = split.column()
299         col.prop(md, "falloff")
300         col.prop(md, "force", slider=True)
301
302         col = split.column()
303         col.operator("object.hook_reset", text="Reset")
304         col.operator("object.hook_recenter", text="Recenter")
305
306         if ob.mode == 'EDIT':
307             layout.separator()
308             row = layout.row()
309             row.operator("object.hook_select", text="Select")
310             row.operator("object.hook_assign", text="Assign")
311
312     def LATTICE(self, layout, ob, md):
313         split = layout.split()
314
315         col = split.column()
316         col.label(text="Object:")
317         col.prop(md, "object", text="")
318
319         col = split.column()
320         col.label(text="Vertex Group:")
321         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
322
323     def MASK(self, layout, ob, md):
324         split = layout.split()
325
326         col = split.column()
327         col.label(text="Mode:")
328         col.prop(md, "mode", text="")
329         col = split.column()
330         if md.mode == 'ARMATURE':
331             col.label(text="Armature:")
332             col.prop(md, "armature", text="")
333         elif md.mode == 'VERTEX_GROUP':
334             col.label(text="Vertex Group:")
335             col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
336
337         sub = col.column()
338         sub.active = bool(md.vertex_group)
339         sub.prop(md, "invert_vertex_group")
340
341     def MESH_DEFORM(self, layout, ob, md):
342         split = layout.split()
343
344         col = split.column()
345         sub = col.column()
346         sub.label(text="Object:")
347         sub.prop(md, "object", text="")
348         sub.active = not md.is_bound
349         col = split.column()
350         col.label(text="Vertex Group:")
351         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
352
353         sub = col.column()
354         sub.active = bool(md.vertex_group)
355         sub.prop(md, "invert_vertex_group")
356
357         layout.separator()
358
359         if md.is_bound:
360             layout.operator("object.meshdeform_bind", text="Unbind")
361         else:
362             layout.operator("object.meshdeform_bind", text="Bind")
363
364             row = layout.row()
365             row.prop(md, "precision")
366             row.prop(md, "use_dynamic_bind")
367
368     def MIRROR(self, layout, ob, md):
369         split = layout.split(percentage=0.25)
370
371         col = split.column()
372         col.label(text="Axis:")
373         col.prop(md, "use_x")
374         col.prop(md, "use_y")
375         col.prop(md, "use_z")
376
377         col = split.column()
378         col.label(text="Options:")
379         col.prop(md, "use_mirror_merge", text="Merge")
380         col.prop(md, "use_clip", text="Clipping")
381         col.prop(md, "use_mirror_vertex_groups", text="Vertex Groups")
382
383         col = split.column()
384         col.label(text="Textures:")
385         col.prop(md, "use_mirror_u", text="U")
386         col.prop(md, "use_mirror_v", text="V")
387
388         col = layout.column()
389
390         if md.use_mirror_merge == True:
391             col.prop(md, "merge_threshold")
392         col.label(text="Mirror Object:")
393         col.prop(md, "mirror_object", text="")
394
395     def MULTIRES(self, layout, ob, md):
396         layout.row().prop(md, "subdivision_type", expand=True)
397
398         split = layout.split()
399         col = split.column()
400         col.prop(md, "levels", text="Preview")
401         col.prop(md, "sculpt_levels", text="Sculpt")
402         col.prop(md, "render_levels", text="Render")
403
404         col = split.column()
405
406         col.enabled = ob.mode != 'EDIT'
407         col.operator("object.multires_subdivide", text="Subdivide")
408         col.operator("object.multires_higher_levels_delete", text="Delete Higher")
409         col.operator("object.multires_reshape", text="Reshape")
410         col.operator("object.multires_base_apply", text="Apply Base")
411         col.prop(md, "use_subsurf_uv")
412         col.prop(md, "show_only_control_edges")
413
414         layout.separator()
415
416         col = layout.column()
417         row = col.row()
418         if md.is_external:
419             row.operator("object.multires_external_pack", text="Pack External")
420             row.label()
421             row = col.row()
422             row.prop(md, "filepath", text="")
423         else:
424             row.operator("object.multires_external_save", text="Save External...")
425             row.label()
426
427     def OCEAN(self, layout, ob, md):
428         if not md.is_build_enabled:
429             layout.label("Built without OceanSim modifier")
430             return
431
432         layout.prop(md, "geometry_mode")
433
434         if md.geometry_mode == 'GENERATE':
435             row = layout.row()
436             row.prop(md, "repeat_x")
437             row.prop(md, "repeat_y")
438
439         layout.separator()
440
441         flow = layout.column_flow()
442         flow.prop(md, "time")
443         flow.prop(md, "resolution")
444         flow.prop(md, "spatial_size")
445         flow.prop(md, "depth")
446
447         layout.label("Waves:")
448
449         split = layout.split()
450
451         col = split.column()
452         col.prop(md, "choppiness")
453         col.prop(md, "wave_scale", text="Scale")
454         col.prop(md, "wave_scale_min")
455         col.prop(md, "wind_velocity")
456
457         col = split.column()
458         col.prop(md, "wave_alignment", text="Alignment")
459         sub = col.column()
460         sub.active = md.wave_alignment > 0
461         sub.prop(md, "wave_direction", text="Direction")
462         sub.prop(md, "damping")
463
464         layout.separator()
465
466         layout.prop(md, "use_normals")
467
468         split = layout.split()
469
470         col = split.column()
471         col.prop(md, "use_foam")
472         sub = col.row()
473         sub.active = md.use_foam
474         sub.prop(md, "foam_coverage", text="Coverage")
475
476         col = split.column()
477         col.active = md.use_foam
478         col.label("Foam Data Layer Name:")
479         col.prop(md, "foam_layer_name", text="")
480
481         layout.separator()
482
483         if md.is_cached:
484             layout.operator("object.ocean_bake", text="Free Bake").free = True
485         else:
486             layout.operator("object.ocean_bake")
487
488         split = layout.split()
489         split.enabled = not md.is_cached
490
491         col = split.column(align=True)
492         col.prop(md, "frame_start", text="Start")
493         col.prop(md, "frame_end", text="End")
494
495         col = split.column(align=True)
496         col.label(text="Cache path:")
497         col.prop(md, "filepath", text="")
498
499         #col.prop(md, "bake_foam_fade")
500
501     def PARTICLE_INSTANCE(self, layout, ob, md):
502         layout.prop(md, "object")
503         layout.prop(md, "particle_system_index", text="Particle System")
504
505         split = layout.split()
506         col = split.column()
507         col.label(text="Create From:")
508         col.prop(md, "use_normal")
509         col.prop(md, "use_children")
510         col.prop(md, "use_size")
511
512         col = split.column()
513         col.label(text="Show Particles When:")
514         col.prop(md, "show_alive")
515         col.prop(md, "show_unborn")
516         col.prop(md, "show_dead")
517
518         layout.separator()
519
520         layout.prop(md, "use_path", text="Create Along Paths")
521
522         split = layout.split()
523         split.active = md.use_path
524         col = split.column()
525         col.row().prop(md, "axis", expand=True)
526         col.prop(md, "use_preserve_shape")
527
528         col = split.column()
529         col.prop(md, "position", slider=True)
530         col.prop(md, "random_position", text="Random", slider=True)
531
532     def PARTICLE_SYSTEM(self, layout, ob, md):
533         layout.label(text="Settings can be found inside the Particle context")
534
535     def SCREW(self, layout, ob, md):
536         split = layout.split()
537
538         col = split.column()
539         col.prop(md, "axis")
540         col.prop(md, "object", text="AxisOb")
541         col.prop(md, "angle")
542         col.prop(md, "steps")
543         col.prop(md, "render_steps")
544
545         col = split.column()
546         row = col.row()
547         row.active = (md.object is None or md.use_object_screw_offset == False)
548         row.prop(md, "screw_offset")
549         row = col.row()
550         row.active = (md.object is not None)
551         row.prop(md, "use_object_screw_offset")
552         col.prop(md, "use_normal_calculate")
553         col.prop(md, "use_normal_flip")
554         col.prop(md, "iterations")
555
556     def SHRINKWRAP(self, layout, ob, md):
557         split = layout.split()
558         col = split.column()
559         col.label(text="Target:")
560         col.prop(md, "target", text="")
561         col = split.column()
562         col.label(text="Vertex Group:")
563         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
564
565         split = layout.split()
566
567         col = split.column()
568         col.prop(md, "offset")
569         col.prop(md, "subsurf_levels")
570
571         col = split.column()
572         col.label(text="Mode:")
573         col.prop(md, "wrap_method", text="")
574
575         if md.wrap_method == 'PROJECT':
576             split = layout.split(percentage=0.25)
577
578             col = split.column()
579             col.label(text="Axis:")
580             col.prop(md, "use_project_x")
581             col.prop(md, "use_project_y")
582             col.prop(md, "use_project_z")
583
584             col = split.column()
585             col.label(text="Direction:")
586             col.prop(md, "use_negative_direction")
587             col.prop(md, "use_positive_direction")
588
589             col = split.column()
590             col.label(text="Cull Faces:")
591             col.prop(md, "cull_face", expand=True)
592
593             layout.label(text="Auxiliary Target:")
594             layout.prop(md, "auxiliary_target", text="")
595
596         elif md.wrap_method == 'NEAREST_SURFACEPOINT':
597             layout.prop(md, "use_keep_above_surface")
598
599     def SIMPLE_DEFORM(self, layout, ob, md):
600         split = layout.split()
601
602         col = split.column()
603         col.label(text="Mode:")
604         col.prop(md, "deform_method", text="")
605
606         col = split.column()
607         col.label(text="Vertex Group:")
608         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
609
610         split = layout.split()
611
612         col = split.column()
613         col.label(text="Origin:")
614         col.prop(md, "origin", text="")
615         sub = col.column()
616         sub.active = (md.origin is not None)
617         sub.prop(md, "use_relative")
618
619         col = split.column()
620         col.label(text="Deform:")
621         col.prop(md, "factor")
622         col.prop(md, "limits", slider=True)
623         if md.deform_method in {'TAPER', 'STRETCH'}:
624             col.prop(md, "lock_x")
625             col.prop(md, "lock_y")
626
627     def SMOKE(self, layout, ob, md):
628         layout.label(text="Settings can be found inside the Physics context")
629
630     def SMOOTH(self, layout, ob, md):
631         split = layout.split(percentage=0.25)
632
633         col = split.column()
634         col.label(text="Axis:")
635         col.prop(md, "use_x")
636         col.prop(md, "use_y")
637         col.prop(md, "use_z")
638
639         col = split.column()
640         col.prop(md, "factor")
641         col.prop(md, "iterations")
642         col.label(text="Vertex Group:")
643         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
644
645     def SOFT_BODY(self, layout, ob, md):
646         layout.label(text="Settings can be found inside the Physics context")
647
648     def SOLIDIFY(self, layout, ob, md):
649         split = layout.split()
650
651         col = split.column()
652         col.prop(md, "thickness")
653         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
654
655         col.label(text="Crease:")
656         col.prop(md, "edge_crease_inner", text="Inner")
657         col.prop(md, "edge_crease_outer", text="Outer")
658         col.prop(md, "edge_crease_rim", text="Rim")
659         col.label(text="Material Index Offset:")
660
661         col = split.column()
662
663         col.prop(md, "offset")
664         sub = col.column()
665         sub.active = bool(md.vertex_group)
666         sub.prop(md, "invert_vertex_group", text="Invert")
667         sub.prop(md, "thickness_vertex_group", text="Factor")
668
669         col.prop(md, "use_even_offset")
670         col.prop(md, "use_quality_normals")
671         col.prop(md, "use_rim")
672
673         sub = col.column()
674         row = sub.split(align=True, percentage=0.4)
675         row.prop(md, "material_offset", text="")
676         row = row.row()
677         row.active = md.use_rim
678         row.prop(md, "material_offset_rim", text="Rim")
679
680     def SUBSURF(self, layout, ob, md):
681         layout.row().prop(md, "subdivision_type", expand=True)
682
683         split = layout.split()
684         col = split.column()
685         col.label(text="Subdivisions:")
686         col.prop(md, "levels", text="View")
687         col.prop(md, "render_levels", text="Render")
688
689         col = split.column()
690         col.label(text="Options:")
691         col.prop(md, "use_subsurf_uv")
692         col.prop(md, "show_only_control_edges")
693
694     def SURFACE(self, layout, ob, md):
695         layout.label(text="Settings can be found inside the Physics context")
696
697     def UV_PROJECT(self, layout, ob, md):
698         split = layout.split()
699
700         col = split.column()
701         col.label(text="Image:")
702         col.prop(md, "image", text="")
703
704         col = split.column()
705         col.label(text="UV Map:")
706         col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="")
707
708         split = layout.split()
709         col = split.column()
710         col.prop(md, "use_image_override")
711         col.prop(md, "projector_count", text="Projectors")
712         for proj in md.projectors:
713             col.prop(proj, "object", text="")
714
715         col = split.column()
716         sub = col.column(align=True)
717         sub.prop(md, "aspect_x", text="Aspect X")
718         sub.prop(md, "aspect_y", text="Aspect Y")
719
720         sub = col.column(align=True)
721         sub.prop(md, "scale_x", text="Scale X")
722         sub.prop(md, "scale_y", text="Scale Y")
723
724     def WARP(self, layout, ob, md):
725         use_falloff = (md.falloff_type != 'NONE')
726         split = layout.split()
727
728         col = split.column()
729         col.label(text="From:")
730         col.prop(md, "object_from", text="")
731
732         col.prop(md, "use_volume_preserve")
733
734         col = split.column()
735         col.label(text="To:")
736         col.prop(md, "object_to", text="")
737         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
738
739         col = layout.column()
740
741         row = col.row(align=True)
742         row.prop(md, "strength")
743         if use_falloff:
744             row.prop(md, "falloff_radius")
745
746         col.prop(md, "falloff_type")
747         if use_falloff:
748             if md.falloff_type == 'CURVE':
749                 col.template_curve_mapping(md, "falloff_curve")
750
751         # 2 new columns
752         split = layout.split()
753         col = split.column()
754         col.label(text="Texture:")
755         col.template_ID(md, "texture", new="texture.new")
756
757         col = split.column()
758         col.label(text="Texture Coordinates:")
759         col.prop(md, "texture_coords", text="")
760
761         if md.texture_coords == 'OBJECT':
762             layout.prop(md, "texture_coords_object", text="Object")
763         elif md.texture_coords == 'UV' and ob.type == 'MESH':
764             layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
765
766     def WAVE(self, layout, ob, md):
767         split = layout.split()
768
769         col = split.column()
770         col.label(text="Motion:")
771         col.prop(md, "use_x")
772         col.prop(md, "use_y")
773         col.prop(md, "use_cyclic")
774
775         col = split.column()
776         col.prop(md, "use_normal")
777         sub = col.column()
778         sub.active = md.use_normal
779         sub.prop(md, "use_normal_x", text="X")
780         sub.prop(md, "use_normal_y", text="Y")
781         sub.prop(md, "use_normal_z", text="Z")
782
783         split = layout.split()
784
785         col = split.column()
786         col.label(text="Time:")
787         sub = col.column(align=True)
788         sub.prop(md, "time_offset", text="Offset")
789         sub.prop(md, "lifetime", text="Life")
790         col.prop(md, "damping_time", text="Damping")
791
792         col = split.column()
793         col.label(text="Position:")
794         sub = col.column(align=True)
795         sub.prop(md, "start_position_x", text="X")
796         sub.prop(md, "start_position_y", text="Y")
797         col.prop(md, "falloff_radius", text="Falloff")
798
799         layout.separator()
800
801         layout.prop(md, "start_position_object")
802         layout.prop_search(md, "vertex_group", ob, "vertex_groups")
803         split = layout.split(percentage=0.33)
804         col = split.column()
805         col.label(text="Texture")
806         col = split.column()
807         col.template_ID(md, "texture", new="texture.new")
808         layout.prop(md, "texture_coords")
809         if md.texture_coords == 'MAP_UV' and ob.type == 'MESH':
810             layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
811         elif md.texture_coords == 'OBJECT':
812             layout.prop(md, "texture_coords_object")
813
814         layout.separator()
815
816         split = layout.split()
817
818         col = split.column()
819         col.prop(md, "speed", slider=True)
820         col.prop(md, "height", slider=True)
821
822         col = split.column()
823         col.prop(md, "width", slider=True)
824         col.prop(md, "narrowness", slider=True)
825
826     def REMESH(self, layout, ob, md):
827         layout.prop(md, "mode")
828
829         layout.prop(md, "octree_depth")
830         layout.prop(md, "scale")
831         row = layout.row()
832         row.active = md.mode == "SHARP"
833         row.prop(md, "sharpness")
834
835         layout.prop(md, "remove_disconnected_pieces")
836         row = layout.row()
837         row.active = md.remove_disconnected_pieces
838         row.prop(md, "threshold")
839
840     @staticmethod
841     def vertex_weight_mask(layout, ob, md):
842         layout.label(text="Influence/Mask Options:")
843
844         split = layout.split(percentage=0.4)
845         split.label(text="Global Influence:")
846         split.prop(md, "mask_constant", text="")
847
848         if not md.mask_texture:
849             split = layout.split(percentage=0.4)
850             split.label(text="Vertex Group Mask:")
851             split.prop_search(md, "mask_vertex_group", ob, "vertex_groups", text="")
852
853         if not md.mask_vertex_group:
854             split = layout.split(percentage=0.4)
855             split.label(text="Texture Mask:")
856             split.template_ID(md, "mask_texture", new="texture.new")
857             if md.mask_texture:
858                 split = layout.split()
859
860                 col = split.column()
861                 col.label(text="Texture Coordinates:")
862                 col.prop(md, "mask_tex_mapping", text="")
863
864                 col = split.column()
865                 col.label(text="Use Channel:")
866                 col.prop(md, "mask_tex_use_channel", text="")
867
868                 if md.mask_tex_mapping == 'OBJECT':
869                     layout.prop(md, "mask_tex_map_object", text="Object")
870                 elif md.mask_tex_mapping == 'UV' and ob.type == 'MESH':
871                     layout.prop_search(md, "mask_tex_uv_layer", ob.data, "uv_textures")
872
873     def VERTEX_WEIGHT_EDIT(self, layout, ob, md):
874         split = layout.split()
875         col = split.column()
876         col.label(text="Vertex Group:")
877         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
878
879         col = split.column()
880         col.label(text="Default Weight:")
881         col.prop(md, "default_weight", text="")
882
883         layout.prop(md, "falloff_type")
884         if md.falloff_type == 'CURVE':
885             col = layout.column()
886             col.template_curve_mapping(md, "map_curve")
887
888         split = layout.split(percentage=0.4)
889         split.prop(md, "use_add")
890         row = split.row()
891         row.active = md.use_add
892         row.prop(md, "add_threshold")
893
894         split = layout.split(percentage=0.4)
895         split.prop(md, "use_remove")
896         row = split.row()
897         row.active = md.use_remove
898         row.prop(md, "remove_threshold")
899
900         # Common mask options
901         layout.separator()
902         self.vertex_weight_mask(layout, ob, md)
903
904     def VERTEX_WEIGHT_MIX(self, layout, ob, md):
905         split = layout.split()
906
907         col = split.column()
908         col.label(text="Vertex Group A:")
909         col.prop_search(md, "vertex_group_a", ob, "vertex_groups", text="")
910         col.label(text="Default Weight A:")
911         col.prop(md, "default_weight_a", text="")
912
913         col.label(text="Mix Mode:")
914         col.prop(md, "mix_mode", text="")
915
916         col = split.column()
917         col.label(text="Vertex Group B:")
918         col.prop_search(md, "vertex_group_b", ob, "vertex_groups", text="")
919         col.label(text="Default Weight B:")
920         col.prop(md, "default_weight_b", text="")
921
922         col.label(text="Mix Set:")
923         col.prop(md, "mix_set", text="")
924
925         # Common mask options
926         layout.separator()
927         self.vertex_weight_mask(layout, ob, md)
928
929     def VERTEX_WEIGHT_PROXIMITY(self, layout, ob, md):
930         split = layout.split()
931
932         col = split.column()
933         col.label(text="Vertex Group:")
934         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
935
936         col = split.column()
937         col.label(text="Target Object:")
938         col.prop(md, "target", text="")
939
940         layout.row().prop(md, "proximity_mode", expand=True)
941         if md.proximity_mode == 'GEOMETRY':
942             layout.row().prop(md, "proximity_geometry", expand=True)
943
944         row = layout.row()
945         row.prop(md, "min_dist")
946         row.prop(md, "max_dist")
947
948         layout.prop(md, "falloff_type")
949
950         # Common mask options
951         layout.separator()
952         self.vertex_weight_mask(layout, ob, md)
953
954 if __name__ == "__main__":  # only for live edit.
955     bpy.utils.register_module(__name__)