Merge branch 'master' into blender2.8
[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 from bpy.app.translations import pgettext_iface as iface_
23
24
25 class ModifierButtonsPanel:
26     bl_space_type = 'PROPERTIES'
27     bl_region_type = 'WINDOW'
28     bl_context = "modifier"
29     bl_options = {'HIDE_HEADER'}
30
31
32 class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
33     bl_label = "Modifiers"
34
35     def draw(self, context):
36         layout = self.layout
37
38         ob = context.object
39
40         layout.operator_menu_enum("object.modifier_add", "type")
41
42         for md in ob.modifiers:
43             box = layout.template_modifier(md)
44             if box:
45                 # match enum type to our functions, avoids a lookup table.
46                 getattr(self, md.type)(box, ob, md)
47
48     # the mt.type enum is (ab)used for a lookup on function names
49     # ...to avoid lengthy if statements
50     # so each type must have a function here.
51
52     def ARMATURE(self, layout, ob, md):
53         split = layout.split()
54
55         col = split.column()
56         col.label(text="Object:")
57         col.prop(md, "object", text="")
58         col.prop(md, "use_deform_preserve_volume")
59
60         col = split.column()
61         col.label(text="Bind To:")
62         col.prop(md, "use_vertex_groups", text="Vertex Groups")
63         col.prop(md, "use_bone_envelopes", text="Bone Envelopes")
64
65         layout.separator()
66
67         split = layout.split()
68
69         row = split.row(align=True)
70         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
71         sub = row.row(align=True)
72         sub.active = bool(md.vertex_group)
73         sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
74
75         split.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         col = split.column()
127         col.prop(md, "width")
128         col.prop(md, "segments")
129         col.prop(md, "profile")
130         col.prop(md, "material")
131
132         col = split.column()
133         col.prop(md, "use_only_vertices")
134         col.prop(md, "use_clamp_overlap")
135         col.prop(md, "loop_slide")
136
137         layout.label(text="Limit Method:")
138         layout.row().prop(md, "limit_method", expand=True)
139         if md.limit_method == 'ANGLE':
140             layout.prop(md, "angle_limit")
141         elif md.limit_method == 'VGROUP':
142             layout.label(text="Vertex Group:")
143             layout.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
144
145         layout.label(text="Width Method:")
146         layout.row().prop(md, "offset_type", expand=True)
147
148     def BOOLEAN(self, layout, ob, md):
149         split = layout.split()
150
151         col = split.column()
152         col.label(text="Operation:")
153         col.prop(md, "operation", text="")
154
155         col = split.column()
156         col.label(text="Object:")
157         col.prop(md, "object", text="")
158
159         """
160         layout.prop(md, "use_bmesh")
161         if md.use_bmesh:
162             box = layout.box()
163             box.label("BMesh Options:")
164             box.prop(md, "use_bmesh_separate")
165             box.prop(md, "use_bmesh_dissolve")
166             box.prop(md, "use_bmesh_connect_regions")
167             box.prop(md, "threshold")
168         """
169
170     def BUILD(self, layout, ob, md):
171         split = layout.split()
172
173         col = split.column()
174         col.prop(md, "frame_start")
175         col.prop(md, "frame_duration")
176         col.prop(md, "use_reverse")
177
178         col = split.column()
179         col.prop(md, "use_random_order")
180         sub = col.column()
181         sub.active = md.use_random_order
182         sub.prop(md, "seed")
183
184     def MESH_CACHE(self, layout, ob, md):
185         layout.prop(md, "cache_format")
186         layout.prop(md, "filepath")
187
188         layout.label(text="Evaluation:")
189         layout.prop(md, "factor", slider=True)
190         layout.prop(md, "deform_mode")
191         layout.prop(md, "interpolation")
192
193         layout.label(text="Time Mapping:")
194
195         row = layout.row()
196         row.prop(md, "time_mode", expand=True)
197         row = layout.row()
198         row.prop(md, "play_mode", expand=True)
199         if md.play_mode == 'SCENE':
200             layout.prop(md, "frame_start")
201             layout.prop(md, "frame_scale")
202         else:
203             time_mode = md.time_mode
204             if time_mode == 'FRAME':
205                 layout.prop(md, "eval_frame")
206             elif time_mode == 'TIME':
207                 layout.prop(md, "eval_time")
208             elif time_mode == 'FACTOR':
209                 layout.prop(md, "eval_factor")
210
211         layout.label(text="Axis Mapping:")
212         split = layout.split(percentage=0.5, align=True)
213         split.alert = (md.forward_axis[-1] == md.up_axis[-1])
214         split.label("Forward/Up Axis:")
215         split.prop(md, "forward_axis", text="")
216         split.prop(md, "up_axis", text="")
217         split = layout.split(percentage=0.5)
218         split.label(text="Flip Axis:")
219         row = split.row()
220         row.prop(md, "flip_axis")
221
222     def CAST(self, layout, ob, md):
223         split = layout.split(percentage=0.25)
224
225         split.label(text="Cast Type:")
226         split.prop(md, "cast_type", text="")
227
228         split = layout.split(percentage=0.25)
229
230         col = split.column()
231         col.prop(md, "use_x")
232         col.prop(md, "use_y")
233         col.prop(md, "use_z")
234
235         col = split.column()
236         col.prop(md, "factor")
237         col.prop(md, "radius")
238         col.prop(md, "size")
239         col.prop(md, "use_radius_as_size")
240
241         split = layout.split()
242
243         col = split.column()
244         col.label(text="Vertex Group:")
245         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
246         col = split.column()
247         col.label(text="Control Object:")
248         col.prop(md, "object", text="")
249         if md.object:
250             col.prop(md, "use_transform")
251
252     def CLOTH(self, layout, ob, md):
253         layout.label(text="Settings are inside the Physics tab")
254
255     def COLLISION(self, layout, ob, md):
256         layout.label(text="Settings are inside the Physics tab")
257
258     def CURVE(self, layout, ob, md):
259         split = layout.split()
260
261         col = split.column()
262         col.label(text="Object:")
263         col.prop(md, "object", text="")
264         col = split.column()
265         col.label(text="Vertex Group:")
266         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
267         layout.label(text="Deformation Axis:")
268         layout.row().prop(md, "deform_axis", expand=True)
269
270     def DECIMATE(self, layout, ob, md):
271         decimate_type = md.decimate_type
272
273         row = layout.row()
274         row.prop(md, "decimate_type", expand=True)
275
276         if decimate_type == 'COLLAPSE':
277             has_vgroup = bool(md.vertex_group)
278             layout.prop(md, "ratio")
279
280             split = layout.split()
281
282             col = split.column()
283             row = col.row(align=True)
284             row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
285             row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
286
287             layout_info = col
288
289             col = split.column()
290             row = col.row()
291             row.active = has_vgroup
292             row.prop(md, "vertex_group_factor")
293
294             col.prop(md, "use_collapse_triangulate")
295             row = col.split(percentage=0.75)
296             row.prop(md, "use_symmetry")
297             row.prop(md, "symmetry_axis", text="")
298
299         elif decimate_type == 'UNSUBDIV':
300             layout.prop(md, "iterations")
301             layout_info = layout
302         else:  # decimate_type == 'DISSOLVE':
303             layout.prop(md, "angle_limit")
304             layout.prop(md, "use_dissolve_boundaries")
305             layout.label("Delimit:")
306             row = layout.row()
307             row.prop(md, "delimit")
308             layout_info = layout
309
310         layout_info.label(text=iface_("Faces: %d") % md.face_count, translate=False)
311
312     def DISPLACE(self, layout, ob, md):
313         has_texture = (md.texture is not None)
314
315         col = layout.column(align=True)
316         col.label(text="Texture:")
317         col.template_ID(md, "texture", new="texture.new")
318
319         split = layout.split()
320
321         col = split.column(align=True)
322         col.label(text="Direction:")
323         col.prop(md, "direction", text="")
324         col.label(text="Vertex Group:")
325         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
326
327         col = split.column(align=True)
328         col.active = has_texture
329         col.label(text="Texture Coordinates:")
330         col.prop(md, "texture_coords", text="")
331         if md.texture_coords == 'OBJECT':
332             col.label(text="Object:")
333             col.prop(md, "texture_coords_object", text="")
334         elif md.texture_coords == 'UV' and ob.type == 'MESH':
335             col.label(text="UV Map:")
336             col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="")
337
338         layout.separator()
339
340         row = layout.row()
341         row.prop(md, "mid_level")
342         row.prop(md, "strength")
343
344     def DYNAMIC_PAINT(self, layout, ob, md):
345         layout.label(text="Settings are inside the Physics tab")
346
347     def EDGE_SPLIT(self, layout, ob, md):
348         split = layout.split()
349
350         col = split.column()
351         col.prop(md, "use_edge_angle", text="Edge Angle")
352         sub = col.column()
353         sub.active = md.use_edge_angle
354         sub.prop(md, "split_angle")
355
356         split.prop(md, "use_edge_sharp", text="Sharp Edges")
357
358     def EXPLODE(self, layout, ob, md):
359         split = layout.split()
360
361         col = split.column()
362         col.label(text="Vertex group:")
363         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
364         sub = col.column()
365         sub.active = bool(md.vertex_group)
366         sub.prop(md, "protect")
367         col.label(text="Particle UV")
368         col.prop_search(md, "particle_uv", ob.data, "uv_textures", text="")
369
370         col = split.column()
371         col.prop(md, "use_edge_cut")
372         col.prop(md, "show_unborn")
373         col.prop(md, "show_alive")
374         col.prop(md, "show_dead")
375         col.prop(md, "use_size")
376
377         layout.operator("object.explode_refresh", text="Refresh")
378
379     def FLUID_SIMULATION(self, layout, ob, md):
380         layout.label(text="Settings are inside the Physics tab")
381
382     def HOOK(self, layout, ob, md):
383         use_falloff = (md.falloff_type != 'NONE')
384         split = layout.split()
385
386         col = split.column()
387         col.label(text="Object:")
388         col.prop(md, "object", text="")
389         if md.object and md.object.type == 'ARMATURE':
390             col.label(text="Bone:")
391             col.prop_search(md, "subtarget", md.object.data, "bones", text="")
392         col = split.column()
393         col.label(text="Vertex Group:")
394         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
395
396         layout.separator()
397
398         row = layout.row(align=True)
399         if use_falloff:
400             row.prop(md, "falloff_radius")
401         row.prop(md, "strength", slider=True)
402         layout.prop(md, "falloff_type")
403
404         col = layout.column()
405         if use_falloff:
406             if md.falloff_type == 'CURVE':
407                 col.template_curve_mapping(md, "falloff_curve")
408
409         split = layout.split()
410
411         col = split.column()
412         col.prop(md, "use_falloff_uniform")
413
414         if ob.mode == 'EDIT':
415             row = col.row(align=True)
416             row.operator("object.hook_reset", text="Reset")
417             row.operator("object.hook_recenter", text="Recenter")
418
419             row = layout.row(align=True)
420             row.operator("object.hook_select", text="Select")
421             row.operator("object.hook_assign", text="Assign")
422
423     def LAPLACIANDEFORM(self, layout, ob, md):
424         is_bind = md.is_bind
425
426         layout.prop(md, "iterations")
427
428         row = layout.row()
429         row.active = not is_bind
430         row.label(text="Anchors Vertex Group:")
431
432         row = layout.row()
433         row.enabled = not is_bind
434         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
435
436         layout.separator()
437
438         row = layout.row()
439         row.enabled = bool(md.vertex_group)
440         row.operator("object.laplaciandeform_bind", text="Unbind" if is_bind else "Bind")
441
442     def LAPLACIANSMOOTH(self, layout, ob, md):
443         layout.prop(md, "iterations")
444
445         split = layout.split(percentage=0.25)
446
447         col = split.column()
448         col.label(text="Axis:")
449         col.prop(md, "use_x")
450         col.prop(md, "use_y")
451         col.prop(md, "use_z")
452
453         col = split.column()
454         col.label(text="Lambda:")
455         col.prop(md, "lambda_factor", text="Factor")
456         col.prop(md, "lambda_border", text="Border")
457
458         col.separator()
459         col.prop(md, "use_volume_preserve")
460         col.prop(md, "use_normalized")
461
462         layout.label(text="Vertex Group:")
463         layout.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
464
465     def LATTICE(self, layout, ob, md):
466         split = layout.split()
467
468         col = split.column()
469         col.label(text="Object:")
470         col.prop(md, "object", text="")
471
472         col = split.column()
473         col.label(text="Vertex Group:")
474         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
475
476         layout.separator()
477         layout.prop(md, "strength", slider=True)
478
479     def MASK(self, layout, ob, md):
480         split = layout.split()
481
482         col = split.column()
483         col.label(text="Mode:")
484         col.prop(md, "mode", text="")
485
486         col = split.column()
487         if md.mode == 'ARMATURE':
488             col.label(text="Armature:")
489             row = col.row(align=True)
490             row.prop(md, "armature", text="")
491             sub = row.row(align=True)
492             sub.active = (md.armature is not None)
493             sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
494         elif md.mode == 'VERTEX_GROUP':
495             col.label(text="Vertex Group:")
496             row = col.row(align=True)
497             row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
498             sub = row.row(align=True)
499             sub.active = bool(md.vertex_group)
500             sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
501
502     def MESH_DEFORM(self, layout, ob, md):
503         split = layout.split()
504
505         col = split.column()
506         col.enabled = not md.is_bound
507         col.label(text="Object:")
508         col.prop(md, "object", text="")
509
510         col = split.column()
511         col.label(text="Vertex Group:")
512         row = col.row(align=True)
513         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
514         sub = row.row(align=True)
515         sub.active = bool(md.vertex_group)
516         sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
517
518         layout.separator()
519         row = layout.row()
520         row.enabled = not md.is_bound
521         row.prop(md, "precision")
522         row.prop(md, "use_dynamic_bind")
523
524         layout.separator()
525         if md.is_bound:
526             layout.operator("object.meshdeform_bind", text="Unbind")
527         else:
528             layout.operator("object.meshdeform_bind", text="Bind")
529
530     def MIRROR(self, layout, ob, md):
531         split = layout.split(percentage=0.25)
532
533         col = split.column()
534         col.label(text="Axis:")
535         col.prop(md, "use_x")
536         col.prop(md, "use_y")
537         col.prop(md, "use_z")
538
539         col = split.column()
540         col.label(text="Options:")
541         col.prop(md, "use_mirror_merge", text="Merge")
542         col.prop(md, "use_clip", text="Clipping")
543         col.prop(md, "use_mirror_vertex_groups", text="Vertex Groups")
544
545         col = split.column()
546         col.label(text="Textures:")
547         col.prop(md, "use_mirror_u", text="U")
548         col.prop(md, "use_mirror_v", text="V")
549
550         col = layout.column()
551
552         if md.use_mirror_merge is True:
553             col.prop(md, "merge_threshold")
554         col.label(text="Mirror Object:")
555         col.prop(md, "mirror_object", text="")
556
557     def MULTIRES(self, layout, ob, md):
558         layout.row().prop(md, "subdivision_type", expand=True)
559
560         split = layout.split()
561         col = split.column()
562         col.prop(md, "levels", text="Preview")
563         col.prop(md, "sculpt_levels", text="Sculpt")
564         col.prop(md, "render_levels", text="Render")
565
566         col = split.column()
567
568         col.enabled = ob.mode != 'EDIT'
569         col.operator("object.multires_subdivide", text="Subdivide")
570         col.operator("object.multires_higher_levels_delete", text="Delete Higher")
571         col.operator("object.multires_reshape", text="Reshape")
572         col.operator("object.multires_base_apply", text="Apply Base")
573         col.prop(md, "use_subsurf_uv")
574         col.prop(md, "show_only_control_edges")
575
576         layout.separator()
577
578         col = layout.column()
579         row = col.row()
580         if md.is_external:
581             row.operator("object.multires_external_pack", text="Pack External")
582             row.label()
583             row = col.row()
584             row.prop(md, "filepath", text="")
585         else:
586             row.operator("object.multires_external_save", text="Save External...")
587             row.label()
588
589     def OCEAN(self, layout, ob, md):
590         if not bpy.app.build_options.mod_oceansim:
591             layout.label("Built without OceanSim modifier")
592             return
593
594         layout.prop(md, "geometry_mode")
595
596         if md.geometry_mode == 'GENERATE':
597             row = layout.row()
598             row.prop(md, "repeat_x")
599             row.prop(md, "repeat_y")
600
601         layout.separator()
602
603         split = layout.split()
604
605         col = split.column()
606         col.prop(md, "time")
607         col.prop(md, "depth")
608         col.prop(md, "random_seed")
609
610         col = split.column()
611         col.prop(md, "resolution")
612         col.prop(md, "size")
613         col.prop(md, "spatial_size")
614
615         layout.label("Waves:")
616
617         split = layout.split()
618
619         col = split.column()
620         col.prop(md, "choppiness")
621         col.prop(md, "wave_scale", text="Scale")
622         col.prop(md, "wave_scale_min")
623         col.prop(md, "wind_velocity")
624
625         col = split.column()
626         col.prop(md, "wave_alignment", text="Alignment")
627         sub = col.column()
628         sub.active = (md.wave_alignment > 0.0)
629         sub.prop(md, "wave_direction", text="Direction")
630         sub.prop(md, "damping")
631
632         layout.separator()
633
634         layout.prop(md, "use_normals")
635
636         split = layout.split()
637
638         col = split.column()
639         col.prop(md, "use_foam")
640         sub = col.row()
641         sub.active = md.use_foam
642         sub.prop(md, "foam_coverage", text="Coverage")
643
644         col = split.column()
645         col.active = md.use_foam
646         col.label("Foam Data Layer Name:")
647         col.prop(md, "foam_layer_name", text="")
648
649         layout.separator()
650
651         if md.is_cached:
652             layout.operator("object.ocean_bake", text="Free Bake").free = True
653         else:
654             layout.operator("object.ocean_bake").free = False
655
656         split = layout.split()
657         split.enabled = not md.is_cached
658
659         col = split.column(align=True)
660         col.prop(md, "frame_start", text="Start")
661         col.prop(md, "frame_end", text="End")
662
663         col = split.column(align=True)
664         col.label(text="Cache path:")
665         col.prop(md, "filepath", text="")
666
667         split = layout.split()
668         split.enabled = not md.is_cached
669
670         col = split.column()
671         col.active = md.use_foam
672         col.prop(md, "bake_foam_fade")
673
674         col = split.column()
675
676     def SCREW(self, layout, ob, md):
677         split = layout.split()
678
679         col = split.column()
680         col.prop(md, "axis")
681         col.prop(md, "object", text="AxisOb")
682         col.prop(md, "angle")
683         col.prop(md, "steps")
684         col.prop(md, "render_steps")
685         col.prop(md, "use_smooth_shade")
686
687         col = split.column()
688         row = col.row()
689         row.active = (md.object is None or md.use_object_screw_offset is False)
690         row.prop(md, "screw_offset")
691         row = col.row()
692         row.active = (md.object is not None)
693         row.prop(md, "use_object_screw_offset")
694         col.prop(md, "use_normal_calculate")
695         col.prop(md, "use_normal_flip")
696         col.prop(md, "iterations")
697         col.prop(md, "use_stretch_u")
698         col.prop(md, "use_stretch_v")
699
700     def SHRINKWRAP(self, layout, ob, md):
701         split = layout.split()
702         col = split.column()
703         col.label(text="Target:")
704         col.prop(md, "target", text="")
705         col = split.column()
706         col.label(text="Vertex Group:")
707         row = col.row(align=True)
708         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
709         row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
710
711         split = layout.split()
712
713         col = split.column()
714         col.prop(md, "offset")
715
716         col = split.column()
717         col.label(text="Mode:")
718         col.prop(md, "wrap_method", text="")
719
720         if md.wrap_method == 'PROJECT':
721             split = layout.split()
722             col = split.column()
723             col.prop(md, "subsurf_levels")
724             col = split.column()
725
726             col.prop(md, "project_limit", text="Limit")
727             split = layout.split(percentage=0.25)
728
729             col = split.column()
730             col.label(text="Axis:")
731             col.prop(md, "use_project_x")
732             col.prop(md, "use_project_y")
733             col.prop(md, "use_project_z")
734
735             col = split.column()
736             col.label(text="Direction:")
737             col.prop(md, "use_negative_direction")
738             col.prop(md, "use_positive_direction")
739
740             col = split.column()
741             col.label(text="Cull Faces:")
742             col.prop(md, "cull_face", expand=True)
743
744             layout.prop(md, "auxiliary_target")
745
746         elif md.wrap_method == 'NEAREST_SURFACEPOINT':
747             layout.prop(md, "use_keep_above_surface")
748
749     def SIMPLE_DEFORM(self, layout, ob, md):
750
751         layout.row().prop(md, "deform_method", expand=True)
752
753         split = layout.split()
754
755         col = split.column()
756         col.label(text="Vertex Group:")
757         row = col.row(align=True)
758         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
759         row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
760
761         split = layout.split()
762
763         col = split.column()
764         col.label(text="Axis, Origin:")
765         col.prop(md, "origin", text="")
766
767         if md.deform_method in {'TAPER', 'STRETCH', 'TWIST'}:
768             col.label(text="Lock:")
769             col.prop(md, "lock_x")
770             col.prop(md, "lock_y")
771
772         col = split.column()
773         col.label(text="Deform:")
774         if md.deform_method in {'TAPER', 'STRETCH'}:
775             col.prop(md, "factor")
776         else:
777             col.prop(md, "angle")
778         col.prop(md, "limits", slider=True)
779
780     def SMOKE(self, layout, ob, md):
781         layout.label(text="Settings are inside the Physics tab")
782
783     def SMOOTH(self, layout, ob, md):
784         split = layout.split(percentage=0.25)
785
786         col = split.column()
787         col.label(text="Axis:")
788         col.prop(md, "use_x")
789         col.prop(md, "use_y")
790         col.prop(md, "use_z")
791
792         col = split.column()
793         col.prop(md, "factor")
794         col.prop(md, "iterations")
795         col.label(text="Vertex Group:")
796         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
797
798     def SOFT_BODY(self, layout, ob, md):
799         layout.label(text="Settings are inside the Physics tab")
800
801     def SOLIDIFY(self, layout, ob, md):
802         split = layout.split()
803
804         col = split.column()
805         col.prop(md, "thickness")
806         col.prop(md, "thickness_clamp")
807
808         col.separator()
809
810         row = col.row(align=True)
811         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
812         sub = row.row(align=True)
813         sub.active = bool(md.vertex_group)
814         sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
815
816         sub = col.row()
817         sub.active = bool(md.vertex_group)
818         sub.prop(md, "thickness_vertex_group", text="Factor")
819
820         col.label(text="Crease:")
821         col.prop(md, "edge_crease_inner", text="Inner")
822         col.prop(md, "edge_crease_outer", text="Outer")
823         col.prop(md, "edge_crease_rim", text="Rim")
824
825         col = split.column()
826
827         col.prop(md, "offset")
828         col.prop(md, "use_flip_normals")
829
830         col.prop(md, "use_even_offset")
831         col.prop(md, "use_quality_normals")
832         col.prop(md, "use_rim")
833         col_rim = col.column()
834         col_rim.active = md.use_rim
835         col_rim.prop(md, "use_rim_only")
836
837         col.separator()
838
839         col.label(text="Material Index Offset:")
840
841         sub = col.column()
842         row = sub.split(align=True, percentage=0.4)
843         row.prop(md, "material_offset", text="")
844         row = row.row(align=True)
845         row.active = md.use_rim
846         row.prop(md, "material_offset_rim", text="Rim")
847
848     def SUBSURF(self, layout, ob, md):
849         layout.row().prop(md, "subdivision_type", expand=True)
850
851         split = layout.split()
852         col = split.column()
853         col.label(text="Subdivisions:")
854         col.prop(md, "levels", text="View")
855         col.prop(md, "render_levels", text="Render")
856
857         col = split.column()
858         col.label(text="Options:")
859         col.prop(md, "use_subsurf_uv")
860         col.prop(md, "show_only_control_edges")
861         if hasattr(md, "use_opensubdiv"):
862             col.prop(md, "use_opensubdiv")
863
864     def SURFACE(self, layout, ob, md):
865         layout.label(text="Settings are inside the Physics tab")
866
867     def UV_PROJECT(self, layout, ob, md):
868         split = layout.split()
869
870         col = split.column()
871         col.label(text="Image:")
872         col.prop(md, "image", text="")
873
874         col = split.column()
875         col.label(text="UV Map:")
876         col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="")
877
878         split = layout.split()
879         col = split.column()
880         col.prop(md, "use_image_override")
881         col.prop(md, "projector_count", text="Projectors")
882         for proj in md.projectors:
883             col.prop(proj, "object", text="")
884
885         col = split.column()
886         sub = col.column(align=True)
887         sub.prop(md, "aspect_x", text="Aspect X")
888         sub.prop(md, "aspect_y", text="Aspect Y")
889
890         sub = col.column(align=True)
891         sub.prop(md, "scale_x", text="Scale X")
892         sub.prop(md, "scale_y", text="Scale Y")
893
894     def WARP(self, layout, ob, md):
895         use_falloff = (md.falloff_type != 'NONE')
896         split = layout.split()
897
898         col = split.column()
899         col.label(text="From:")
900         col.prop(md, "object_from", text="")
901
902         col.prop(md, "use_volume_preserve")
903
904         col = split.column()
905         col.label(text="To:")
906         col.prop(md, "object_to", text="")
907         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
908
909         col = layout.column()
910
911         row = col.row(align=True)
912         row.prop(md, "strength")
913         if use_falloff:
914             row.prop(md, "falloff_radius")
915
916         col.prop(md, "falloff_type")
917         if use_falloff:
918             if md.falloff_type == 'CURVE':
919                 col.template_curve_mapping(md, "falloff_curve")
920
921         # 2 new columns
922         split = layout.split()
923         col = split.column()
924         col.label(text="Texture:")
925         col.template_ID(md, "texture", new="texture.new")
926
927         col = split.column()
928         col.label(text="Texture Coordinates:")
929         col.prop(md, "texture_coords", text="")
930
931         if md.texture_coords == 'OBJECT':
932             layout.prop(md, "texture_coords_object", text="Object")
933         elif md.texture_coords == 'UV' and ob.type == 'MESH':
934             layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
935
936     def WAVE(self, layout, ob, md):
937         split = layout.split()
938
939         col = split.column()
940         col.label(text="Motion:")
941         col.prop(md, "use_x")
942         col.prop(md, "use_y")
943         col.prop(md, "use_cyclic")
944
945         col = split.column()
946         col.prop(md, "use_normal")
947         sub = col.column()
948         sub.active = md.use_normal
949         sub.prop(md, "use_normal_x", text="X")
950         sub.prop(md, "use_normal_y", text="Y")
951         sub.prop(md, "use_normal_z", text="Z")
952
953         split = layout.split()
954
955         col = split.column()
956         col.label(text="Time:")
957         sub = col.column(align=True)
958         sub.prop(md, "time_offset", text="Offset")
959         sub.prop(md, "lifetime", text="Life")
960         col.prop(md, "damping_time", text="Damping")
961
962         col = split.column()
963         col.label(text="Position:")
964         sub = col.column(align=True)
965         sub.prop(md, "start_position_x", text="X")
966         sub.prop(md, "start_position_y", text="Y")
967         col.prop(md, "falloff_radius", text="Falloff")
968
969         layout.separator()
970
971         layout.prop(md, "start_position_object")
972         layout.prop_search(md, "vertex_group", ob, "vertex_groups")
973         split = layout.split(percentage=0.33)
974         col = split.column()
975         col.label(text="Texture")
976         col = split.column()
977         col.template_ID(md, "texture", new="texture.new")
978         layout.prop(md, "texture_coords")
979         if md.texture_coords == 'UV' and ob.type == 'MESH':
980             layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
981         elif md.texture_coords == 'OBJECT':
982             layout.prop(md, "texture_coords_object")
983
984         layout.separator()
985
986         split = layout.split()
987
988         col = split.column()
989         col.prop(md, "speed", slider=True)
990         col.prop(md, "height", slider=True)
991
992         col = split.column()
993         col.prop(md, "width", slider=True)
994         col.prop(md, "narrowness", slider=True)
995
996     def REMESH(self, layout, ob, md):
997         layout.prop(md, "mode")
998
999         row = layout.row()
1000         row.prop(md, "octree_depth")
1001         row.prop(md, "scale")
1002
1003         if md.mode == 'SHARP':
1004             layout.prop(md, "sharpness")
1005
1006         layout.prop(md, "use_smooth_shade")
1007         layout.prop(md, "use_remove_disconnected")
1008         row = layout.row()
1009         row.active = md.use_remove_disconnected
1010         row.prop(md, "threshold")
1011
1012     @staticmethod
1013     def vertex_weight_mask(layout, ob, md):
1014         layout.label(text="Influence/Mask Options:")
1015
1016         split = layout.split(percentage=0.4)
1017         split.label(text="Global Influence:")
1018         split.prop(md, "mask_constant", text="")
1019
1020         if not md.mask_texture:
1021             split = layout.split(percentage=0.4)
1022             split.label(text="Vertex Group Mask:")
1023             split.prop_search(md, "mask_vertex_group", ob, "vertex_groups", text="")
1024
1025         if not md.mask_vertex_group:
1026             split = layout.split(percentage=0.4)
1027             split.label(text="Texture Mask:")
1028             split.template_ID(md, "mask_texture", new="texture.new")
1029             if md.mask_texture:
1030                 split = layout.split()
1031
1032                 col = split.column()
1033                 col.label(text="Texture Coordinates:")
1034                 col.prop(md, "mask_tex_mapping", text="")
1035
1036                 col = split.column()
1037                 col.label(text="Use Channel:")
1038                 col.prop(md, "mask_tex_use_channel", text="")
1039
1040                 if md.mask_tex_mapping == 'OBJECT':
1041                     layout.prop(md, "mask_tex_map_object", text="Object")
1042                 elif md.mask_tex_mapping == 'UV' and ob.type == 'MESH':
1043                     layout.prop_search(md, "mask_tex_uv_layer", ob.data, "uv_textures")
1044
1045     def VERTEX_WEIGHT_EDIT(self, layout, ob, md):
1046         split = layout.split()
1047
1048         col = split.column()
1049         col.label(text="Vertex Group:")
1050         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1051
1052         col.label(text="Default Weight:")
1053         col.prop(md, "default_weight", text="")
1054
1055         col = split.column()
1056         col.prop(md, "use_add")
1057         sub = col.column()
1058         sub.active = md.use_add
1059         sub.prop(md, "add_threshold")
1060
1061         col = col.column()
1062         col.prop(md, "use_remove")
1063         sub = col.column()
1064         sub.active = md.use_remove
1065         sub.prop(md, "remove_threshold")
1066
1067         layout.separator()
1068
1069         layout.prop(md, "falloff_type")
1070         if md.falloff_type == 'CURVE':
1071             layout.template_curve_mapping(md, "map_curve")
1072
1073         # Common mask options
1074         layout.separator()
1075         self.vertex_weight_mask(layout, ob, md)
1076
1077     def VERTEX_WEIGHT_MIX(self, layout, ob, md):
1078         split = layout.split()
1079
1080         col = split.column()
1081         col.label(text="Vertex Group A:")
1082         col.prop_search(md, "vertex_group_a", ob, "vertex_groups", text="")
1083         col.label(text="Default Weight A:")
1084         col.prop(md, "default_weight_a", text="")
1085
1086         col.label(text="Mix Mode:")
1087         col.prop(md, "mix_mode", text="")
1088
1089         col = split.column()
1090         col.label(text="Vertex Group B:")
1091         col.prop_search(md, "vertex_group_b", ob, "vertex_groups", text="")
1092         col.label(text="Default Weight B:")
1093         col.prop(md, "default_weight_b", text="")
1094
1095         col.label(text="Mix Set:")
1096         col.prop(md, "mix_set", text="")
1097
1098         # Common mask options
1099         layout.separator()
1100         self.vertex_weight_mask(layout, ob, md)
1101
1102     def VERTEX_WEIGHT_PROXIMITY(self, layout, ob, md):
1103         split = layout.split()
1104
1105         col = split.column()
1106         col.label(text="Vertex Group:")
1107         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1108
1109         col = split.column()
1110         col.label(text="Target Object:")
1111         col.prop(md, "target", text="")
1112
1113         split = layout.split()
1114
1115         col = split.column()
1116         col.label(text="Distance:")
1117         col.prop(md, "proximity_mode", text="")
1118         if md.proximity_mode == 'GEOMETRY':
1119             col.row().prop(md, "proximity_geometry")
1120
1121         col = split.column()
1122         col.label()
1123         col.prop(md, "min_dist")
1124         col.prop(md, "max_dist")
1125
1126         layout.separator()
1127         layout.prop(md, "falloff_type")
1128
1129         # Common mask options
1130         layout.separator()
1131         self.vertex_weight_mask(layout, ob, md)
1132
1133     def SKIN(self, layout, ob, md):
1134         row = layout.row()
1135         row.operator("object.skin_armature_create", text="Create Armature")
1136         row.operator("mesh.customdata_skin_add")
1137
1138         layout.separator()
1139
1140         row = layout.row(align=True)
1141         row.prop(md, "branch_smoothing")
1142         row.prop(md, "use_smooth_shade")
1143
1144         split = layout.split()
1145
1146         col = split.column()
1147         col.label(text="Selected Vertices:")
1148         sub = col.column(align=True)
1149         sub.operator("object.skin_loose_mark_clear", text="Mark Loose").action = 'MARK'
1150         sub.operator("object.skin_loose_mark_clear", text="Clear Loose").action = 'CLEAR'
1151
1152         sub = col.column()
1153         sub.operator("object.skin_root_mark", text="Mark Root")
1154         sub.operator("object.skin_radii_equalize", text="Equalize Radii")
1155
1156         col = split.column()
1157         col.label(text="Symmetry Axes:")
1158         col.prop(md, "use_x_symmetry")
1159         col.prop(md, "use_y_symmetry")
1160         col.prop(md, "use_z_symmetry")
1161
1162     def TRIANGULATE(self, layout, ob, md):
1163         row = layout.row()
1164
1165         col = row.column()
1166         col.label(text="Quad Method:")
1167         col.prop(md, "quad_method", text="")
1168         col = row.column()
1169         col.label(text="Ngon Method:")
1170         col.prop(md, "ngon_method", text="")
1171
1172     def UV_WARP(self, layout, ob, md):
1173         split = layout.split()
1174         col = split.column()
1175         col.prop(md, "center")
1176
1177         col = split.column()
1178         col.label(text="UV Axis:")
1179         col.prop(md, "axis_u", text="")
1180         col.prop(md, "axis_v", text="")
1181
1182         split = layout.split()
1183         col = split.column()
1184         col.label(text="From:")
1185         col.prop(md, "object_from", text="")
1186
1187         col = split.column()
1188         col.label(text="To:")
1189         col.prop(md, "object_to", text="")
1190
1191         split = layout.split()
1192         col = split.column()
1193         obj = md.object_from
1194         if obj and obj.type == 'ARMATURE':
1195             col.label(text="Bone:")
1196             col.prop_search(md, "bone_from", obj.data, "bones", text="")
1197
1198         col = split.column()
1199         obj = md.object_to
1200         if obj and obj.type == 'ARMATURE':
1201             col.label(text="Bone:")
1202             col.prop_search(md, "bone_to", obj.data, "bones", text="")
1203
1204         split = layout.split()
1205
1206         col = split.column()
1207         col.label(text="Vertex Group:")
1208         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1209
1210         col = split.column()
1211         col.label(text="UV Map:")
1212         col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="")
1213
1214     def WIREFRAME(self, layout, ob, md):
1215         has_vgroup = bool(md.vertex_group)
1216
1217         split = layout.split()
1218
1219         col = split.column()
1220         col.prop(md, "thickness", text="Thickness")
1221
1222         row = col.row(align=True)
1223         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1224         sub = row.row(align=True)
1225         sub.active = has_vgroup
1226         sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
1227         row = col.row(align=True)
1228         row.active = has_vgroup
1229         row.prop(md, "thickness_vertex_group", text="Factor")
1230
1231         col.prop(md, "use_crease", text="Crease Edges")
1232         col.prop(md, "crease_weight", text="Crease Weight")
1233
1234         col = split.column()
1235
1236         col.prop(md, "offset")
1237         col.prop(md, "use_even_offset", text="Even Thickness")
1238         col.prop(md, "use_relative_offset", text="Relative Thickness")
1239         col.prop(md, "use_boundary", text="Boundary")
1240         col.prop(md, "use_replace", text="Replace Original")
1241
1242         col.prop(md, "material_offset", text="Material Offset")
1243
1244     def DATA_TRANSFER(self, layout, ob, md):
1245         row = layout.row(align=True)
1246         row.prop(md, "object")
1247         sub = row.row(align=True)
1248         sub.active = bool(md.object)
1249         sub.prop(md, "use_object_transform", text="", icon='GROUP')
1250
1251         layout.separator()
1252
1253         split = layout.split(0.333)
1254         split.prop(md, "use_vert_data")
1255         use_vert = md.use_vert_data
1256         row = split.row()
1257         row.active = use_vert
1258         row.prop(md, "vert_mapping", text="")
1259         if use_vert:
1260             col = layout.column(align=True)
1261             split = col.split(0.333, align=True)
1262             sub = split.column(align=True)
1263             sub.prop(md, "data_types_verts")
1264             sub = split.column(align=True)
1265             row = sub.row(align=True)
1266             row.prop(md, "layers_vgroup_select_src", text="")
1267             row.label(icon='RIGHTARROW')
1268             row.prop(md, "layers_vgroup_select_dst", text="")
1269             row = sub.row(align=True)
1270             row.label("", icon='NONE')
1271
1272         layout.separator()
1273
1274         split = layout.split(0.333)
1275         split.prop(md, "use_edge_data")
1276         use_edge = md.use_edge_data
1277         row = split.row()
1278         row.active = use_edge
1279         row.prop(md, "edge_mapping", text="")
1280         if use_edge:
1281             col = layout.column(align=True)
1282             split = col.split(0.333, align=True)
1283             sub = split.column(align=True)
1284             sub.prop(md, "data_types_edges")
1285
1286         layout.separator()
1287
1288         split = layout.split(0.333)
1289         split.prop(md, "use_loop_data")
1290         use_loop = md.use_loop_data
1291         row = split.row()
1292         row.active = use_loop
1293         row.prop(md, "loop_mapping", text="")
1294         if use_loop:
1295             col = layout.column(align=True)
1296             split = col.split(0.333, align=True)
1297             sub = split.column(align=True)
1298             sub.prop(md, "data_types_loops")
1299             sub = split.column(align=True)
1300             row = sub.row(align=True)
1301             row.label("", icon='NONE')
1302             row = sub.row(align=True)
1303             row.prop(md, "layers_vcol_select_src", text="")
1304             row.label(icon='RIGHTARROW')
1305             row.prop(md, "layers_vcol_select_dst", text="")
1306             row = sub.row(align=True)
1307             row.prop(md, "layers_uv_select_src", text="")
1308             row.label(icon='RIGHTARROW')
1309             row.prop(md, "layers_uv_select_dst", text="")
1310             col.prop(md, "islands_precision")
1311
1312         layout.separator()
1313
1314         split = layout.split(0.333)
1315         split.prop(md, "use_poly_data")
1316         use_poly = md.use_poly_data
1317         row = split.row()
1318         row.active = use_poly
1319         row.prop(md, "poly_mapping", text="")
1320         if use_poly:
1321             col = layout.column(align=True)
1322             split = col.split(0.333, align=True)
1323             sub = split.column(align=True)
1324             sub.prop(md, "data_types_polys")
1325
1326         layout.separator()
1327
1328         split = layout.split()
1329         col = split.column()
1330         row = col.row(align=True)
1331         sub = row.row(align=True)
1332         sub.active = md.use_max_distance
1333         sub.prop(md, "max_distance")
1334         row.prop(md, "use_max_distance", text="", icon='STYLUS_PRESSURE')
1335
1336         col = split.column()
1337         col.prop(md, "ray_radius")
1338
1339         layout.separator()
1340
1341         split = layout.split()
1342         col = split.column()
1343         col.prop(md, "mix_mode")
1344         col.prop(md, "mix_factor")
1345
1346         col = split.column()
1347         row = col.row()
1348         row.active = bool(md.object)
1349         row.operator("object.datalayout_transfer", text="Generate Data Layers")
1350         row = col.row(align=True)
1351         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1352         sub = row.row(align=True)
1353         sub.active = bool(md.vertex_group)
1354         sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
1355
1356     def NORMAL_EDIT(self, layout, ob, md):
1357         has_vgroup = bool(md.vertex_group)
1358         needs_object_offset = (((md.mode == 'RADIAL') and not md.target) or
1359                                ((md.mode == 'DIRECTIONAL') and md.use_direction_parallel))
1360
1361         row = layout.row()
1362         row.prop(md, "mode", expand=True)
1363
1364         split = layout.split()
1365
1366         col = split.column()
1367         col.prop(md, "target", text="")
1368         sub = col.column(align=True)
1369         sub.active = needs_object_offset
1370         sub.prop(md, "offset")
1371         row = col.row(align=True)
1372
1373         col = split.column()
1374         row = col.row()
1375         row.active = (md.mode == 'DIRECTIONAL')
1376         row.prop(md, "use_direction_parallel")
1377
1378         subcol = col.column(align=True)
1379         subcol.label("Mix Mode:")
1380         subcol.prop(md, "mix_mode", text="")
1381         subcol.prop(md, "mix_factor")
1382         row = subcol.row(align=True)
1383         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1384         sub = row.row(align=True)
1385         sub.active = has_vgroup
1386         sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
1387         subcol.prop(md, "mix_limit")
1388
1389     def CORRECTIVE_SMOOTH(self, layout, ob, md):
1390         is_bind = md.is_bind
1391
1392         layout.prop(md, "factor", text="Factor")
1393         layout.prop(md, "iterations")
1394
1395         row = layout.row()
1396         row.prop(md, "smooth_type")
1397
1398         split = layout.split()
1399
1400         col = split.column()
1401         col.label(text="Vertex Group:")
1402         row = col.row(align=True)
1403         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1404         row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
1405
1406         col = split.column()
1407         col.prop(md, "use_only_smooth")
1408         col.prop(md, "use_pin_boundary")
1409
1410         layout.prop(md, "rest_source")
1411         if md.rest_source == 'BIND':
1412             layout.operator("object.correctivesmooth_bind", text="Unbind" if is_bind else "Bind")
1413
1414
1415 if __name__ == "__main__":  # only for live edit.
1416     bpy.utils.register_module(__name__)