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