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