aa03863a1987cd70f92de4c753dd5e4a93d236ee
[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 PARTICLE_INSTANCE(self, layout, ob, md):
677         layout.prop(md, "object")
678         layout.prop(md, "particle_system_index", text="Particle System")
679
680         split = layout.split()
681         col = split.column()
682         col.label(text="Create From:")
683         col.prop(md, "use_normal")
684         col.prop(md, "use_children")
685         col.prop(md, "use_size")
686
687         col = split.column()
688         col.label(text="Show Particles When:")
689         col.prop(md, "show_alive")
690         col.prop(md, "show_unborn")
691         col.prop(md, "show_dead")
692
693         layout.separator()
694
695         layout.prop(md, "use_path", text="Create Along Paths")
696
697         split = layout.split()
698         split.active = md.use_path
699         col = split.column()
700         col.row().prop(md, "axis", expand=True)
701         col.prop(md, "use_preserve_shape")
702
703         col = split.column()
704         col.prop(md, "position", slider=True)
705         col.prop(md, "random_position", text="Random", slider=True)
706
707     def PARTICLE_SYSTEM(self, layout, ob, md):
708         layout.label(text="Settings can be found inside the Particle context")
709
710     def SCREW(self, layout, ob, md):
711         split = layout.split()
712
713         col = split.column()
714         col.prop(md, "axis")
715         col.prop(md, "object", text="AxisOb")
716         col.prop(md, "angle")
717         col.prop(md, "steps")
718         col.prop(md, "render_steps")
719         col.prop(md, "use_smooth_shade")
720
721         col = split.column()
722         row = col.row()
723         row.active = (md.object is None or md.use_object_screw_offset is False)
724         row.prop(md, "screw_offset")
725         row = col.row()
726         row.active = (md.object is not None)
727         row.prop(md, "use_object_screw_offset")
728         col.prop(md, "use_normal_calculate")
729         col.prop(md, "use_normal_flip")
730         col.prop(md, "iterations")
731         col.prop(md, "use_stretch_u")
732         col.prop(md, "use_stretch_v")
733
734     def SHRINKWRAP(self, layout, ob, md):
735         split = layout.split()
736         col = split.column()
737         col.label(text="Target:")
738         col.prop(md, "target", text="")
739         col = split.column()
740         col.label(text="Vertex Group:")
741         row = col.row(align=True)
742         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
743         row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
744
745         split = layout.split()
746
747         col = split.column()
748         col.prop(md, "offset")
749
750         col = split.column()
751         col.label(text="Mode:")
752         col.prop(md, "wrap_method", text="")
753
754         if md.wrap_method == 'PROJECT':
755             split = layout.split()
756             col = split.column()
757             col.prop(md, "subsurf_levels")
758             col = split.column()
759
760             col.prop(md, "project_limit", text="Limit")
761             split = layout.split(percentage=0.25)
762
763             col = split.column()
764             col.label(text="Axis:")
765             col.prop(md, "use_project_x")
766             col.prop(md, "use_project_y")
767             col.prop(md, "use_project_z")
768
769             col = split.column()
770             col.label(text="Direction:")
771             col.prop(md, "use_negative_direction")
772             col.prop(md, "use_positive_direction")
773
774             col = split.column()
775             col.label(text="Cull Faces:")
776             col.prop(md, "cull_face", expand=True)
777
778             layout.prop(md, "auxiliary_target")
779
780         elif md.wrap_method == 'NEAREST_SURFACEPOINT':
781             layout.prop(md, "use_keep_above_surface")
782
783     def SIMPLE_DEFORM(self, layout, ob, md):
784
785         layout.row().prop(md, "deform_method", expand=True)
786
787         split = layout.split()
788
789         col = split.column()
790         col.label(text="Vertex Group:")
791         row = col.row(align=True)
792         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
793         row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
794
795         split = layout.split()
796
797         col = split.column()
798         col.label(text="Axis, Origin:")
799         col.prop(md, "origin", text="")
800
801         if md.deform_method in {'TAPER', 'STRETCH', 'TWIST'}:
802             col.label(text="Lock:")
803             col.prop(md, "lock_x")
804             col.prop(md, "lock_y")
805
806         col = split.column()
807         col.label(text="Deform:")
808         if md.deform_method in {'TAPER', 'STRETCH'}:
809             col.prop(md, "factor")
810         else:
811             col.prop(md, "angle")
812         col.prop(md, "limits", slider=True)
813
814     def SMOKE(self, layout, ob, md):
815         layout.label(text="Settings are inside the Physics tab")
816
817     def SMOOTH(self, layout, ob, md):
818         split = layout.split(percentage=0.25)
819
820         col = split.column()
821         col.label(text="Axis:")
822         col.prop(md, "use_x")
823         col.prop(md, "use_y")
824         col.prop(md, "use_z")
825
826         col = split.column()
827         col.prop(md, "factor")
828         col.prop(md, "iterations")
829         col.label(text="Vertex Group:")
830         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
831
832     def SOFT_BODY(self, layout, ob, md):
833         layout.label(text="Settings are inside the Physics tab")
834
835     def SOLIDIFY(self, layout, ob, md):
836         split = layout.split()
837
838         col = split.column()
839         col.prop(md, "thickness")
840         col.prop(md, "thickness_clamp")
841
842         col.separator()
843
844         row = col.row(align=True)
845         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
846         sub = row.row(align=True)
847         sub.active = bool(md.vertex_group)
848         sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
849
850         sub = col.row()
851         sub.active = bool(md.vertex_group)
852         sub.prop(md, "thickness_vertex_group", text="Factor")
853
854         col.label(text="Crease:")
855         col.prop(md, "edge_crease_inner", text="Inner")
856         col.prop(md, "edge_crease_outer", text="Outer")
857         col.prop(md, "edge_crease_rim", text="Rim")
858
859         col = split.column()
860
861         col.prop(md, "offset")
862         col.prop(md, "use_flip_normals")
863
864         col.prop(md, "use_even_offset")
865         col.prop(md, "use_quality_normals")
866         col.prop(md, "use_rim")
867         col_rim = col.column()
868         col_rim.active = md.use_rim
869         col_rim.prop(md, "use_rim_only")
870
871         col.separator()
872
873         col.label(text="Material Index Offset:")
874
875         sub = col.column()
876         row = sub.split(align=True, percentage=0.4)
877         row.prop(md, "material_offset", text="")
878         row = row.row(align=True)
879         row.active = md.use_rim
880         row.prop(md, "material_offset_rim", text="Rim")
881
882     def SUBSURF(self, layout, ob, md):
883         layout.row().prop(md, "subdivision_type", expand=True)
884
885         split = layout.split()
886         col = split.column()
887         col.label(text="Subdivisions:")
888         col.prop(md, "levels", text="View")
889         col.prop(md, "render_levels", text="Render")
890
891         col = split.column()
892         col.label(text="Options:")
893         col.prop(md, "use_subsurf_uv")
894         col.prop(md, "show_only_control_edges")
895         if hasattr(md, "use_opensubdiv"):
896             col.prop(md, "use_opensubdiv")
897
898     def SURFACE(self, layout, ob, md):
899         layout.label(text="Settings are inside the Physics tab")
900
901     def UV_PROJECT(self, layout, ob, md):
902         split = layout.split()
903
904         col = split.column()
905         col.label(text="Image:")
906         col.prop(md, "image", text="")
907
908         col = split.column()
909         col.label(text="UV Map:")
910         col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="")
911
912         split = layout.split()
913         col = split.column()
914         col.prop(md, "use_image_override")
915         col.prop(md, "projector_count", text="Projectors")
916         for proj in md.projectors:
917             col.prop(proj, "object", text="")
918
919         col = split.column()
920         sub = col.column(align=True)
921         sub.prop(md, "aspect_x", text="Aspect X")
922         sub.prop(md, "aspect_y", text="Aspect Y")
923
924         sub = col.column(align=True)
925         sub.prop(md, "scale_x", text="Scale X")
926         sub.prop(md, "scale_y", text="Scale Y")
927
928     def WARP(self, layout, ob, md):
929         use_falloff = (md.falloff_type != 'NONE')
930         split = layout.split()
931
932         col = split.column()
933         col.label(text="From:")
934         col.prop(md, "object_from", text="")
935
936         col.prop(md, "use_volume_preserve")
937
938         col = split.column()
939         col.label(text="To:")
940         col.prop(md, "object_to", text="")
941         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
942
943         col = layout.column()
944
945         row = col.row(align=True)
946         row.prop(md, "strength")
947         if use_falloff:
948             row.prop(md, "falloff_radius")
949
950         col.prop(md, "falloff_type")
951         if use_falloff:
952             if md.falloff_type == 'CURVE':
953                 col.template_curve_mapping(md, "falloff_curve")
954
955         # 2 new columns
956         split = layout.split()
957         col = split.column()
958         col.label(text="Texture:")
959         col.template_ID(md, "texture", new="texture.new")
960
961         col = split.column()
962         col.label(text="Texture Coordinates:")
963         col.prop(md, "texture_coords", text="")
964
965         if md.texture_coords == 'OBJECT':
966             layout.prop(md, "texture_coords_object", text="Object")
967         elif md.texture_coords == 'UV' and ob.type == 'MESH':
968             layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
969
970     def WAVE(self, layout, ob, md):
971         split = layout.split()
972
973         col = split.column()
974         col.label(text="Motion:")
975         col.prop(md, "use_x")
976         col.prop(md, "use_y")
977         col.prop(md, "use_cyclic")
978
979         col = split.column()
980         col.prop(md, "use_normal")
981         sub = col.column()
982         sub.active = md.use_normal
983         sub.prop(md, "use_normal_x", text="X")
984         sub.prop(md, "use_normal_y", text="Y")
985         sub.prop(md, "use_normal_z", text="Z")
986
987         split = layout.split()
988
989         col = split.column()
990         col.label(text="Time:")
991         sub = col.column(align=True)
992         sub.prop(md, "time_offset", text="Offset")
993         sub.prop(md, "lifetime", text="Life")
994         col.prop(md, "damping_time", text="Damping")
995
996         col = split.column()
997         col.label(text="Position:")
998         sub = col.column(align=True)
999         sub.prop(md, "start_position_x", text="X")
1000         sub.prop(md, "start_position_y", text="Y")
1001         col.prop(md, "falloff_radius", text="Falloff")
1002
1003         layout.separator()
1004
1005         layout.prop(md, "start_position_object")
1006         layout.prop_search(md, "vertex_group", ob, "vertex_groups")
1007         split = layout.split(percentage=0.33)
1008         col = split.column()
1009         col.label(text="Texture")
1010         col = split.column()
1011         col.template_ID(md, "texture", new="texture.new")
1012         layout.prop(md, "texture_coords")
1013         if md.texture_coords == 'UV' and ob.type == 'MESH':
1014             layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
1015         elif md.texture_coords == 'OBJECT':
1016             layout.prop(md, "texture_coords_object")
1017
1018         layout.separator()
1019
1020         split = layout.split()
1021
1022         col = split.column()
1023         col.prop(md, "speed", slider=True)
1024         col.prop(md, "height", slider=True)
1025
1026         col = split.column()
1027         col.prop(md, "width", slider=True)
1028         col.prop(md, "narrowness", slider=True)
1029
1030     def REMESH(self, layout, ob, md):
1031         layout.prop(md, "mode")
1032
1033         row = layout.row()
1034         row.prop(md, "octree_depth")
1035         row.prop(md, "scale")
1036
1037         if md.mode == 'SHARP':
1038             layout.prop(md, "sharpness")
1039
1040         layout.prop(md, "use_smooth_shade")
1041         layout.prop(md, "use_remove_disconnected")
1042         row = layout.row()
1043         row.active = md.use_remove_disconnected
1044         row.prop(md, "threshold")
1045
1046     @staticmethod
1047     def vertex_weight_mask(layout, ob, md):
1048         layout.label(text="Influence/Mask Options:")
1049
1050         split = layout.split(percentage=0.4)
1051         split.label(text="Global Influence:")
1052         split.prop(md, "mask_constant", text="")
1053
1054         if not md.mask_texture:
1055             split = layout.split(percentage=0.4)
1056             split.label(text="Vertex Group Mask:")
1057             split.prop_search(md, "mask_vertex_group", ob, "vertex_groups", text="")
1058
1059         if not md.mask_vertex_group:
1060             split = layout.split(percentage=0.4)
1061             split.label(text="Texture Mask:")
1062             split.template_ID(md, "mask_texture", new="texture.new")
1063             if md.mask_texture:
1064                 split = layout.split()
1065
1066                 col = split.column()
1067                 col.label(text="Texture Coordinates:")
1068                 col.prop(md, "mask_tex_mapping", text="")
1069
1070                 col = split.column()
1071                 col.label(text="Use Channel:")
1072                 col.prop(md, "mask_tex_use_channel", text="")
1073
1074                 if md.mask_tex_mapping == 'OBJECT':
1075                     layout.prop(md, "mask_tex_map_object", text="Object")
1076                 elif md.mask_tex_mapping == 'UV' and ob.type == 'MESH':
1077                     layout.prop_search(md, "mask_tex_uv_layer", ob.data, "uv_textures")
1078
1079     def VERTEX_WEIGHT_EDIT(self, layout, ob, md):
1080         split = layout.split()
1081
1082         col = split.column()
1083         col.label(text="Vertex Group:")
1084         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1085
1086         col.label(text="Default Weight:")
1087         col.prop(md, "default_weight", text="")
1088
1089         col = split.column()
1090         col.prop(md, "use_add")
1091         sub = col.column()
1092         sub.active = md.use_add
1093         sub.prop(md, "add_threshold")
1094
1095         col = col.column()
1096         col.prop(md, "use_remove")
1097         sub = col.column()
1098         sub.active = md.use_remove
1099         sub.prop(md, "remove_threshold")
1100
1101         layout.separator()
1102
1103         layout.prop(md, "falloff_type")
1104         if md.falloff_type == 'CURVE':
1105             layout.template_curve_mapping(md, "map_curve")
1106
1107         # Common mask options
1108         layout.separator()
1109         self.vertex_weight_mask(layout, ob, md)
1110
1111     def VERTEX_WEIGHT_MIX(self, layout, ob, md):
1112         split = layout.split()
1113
1114         col = split.column()
1115         col.label(text="Vertex Group A:")
1116         col.prop_search(md, "vertex_group_a", ob, "vertex_groups", text="")
1117         col.label(text="Default Weight A:")
1118         col.prop(md, "default_weight_a", text="")
1119
1120         col.label(text="Mix Mode:")
1121         col.prop(md, "mix_mode", text="")
1122
1123         col = split.column()
1124         col.label(text="Vertex Group B:")
1125         col.prop_search(md, "vertex_group_b", ob, "vertex_groups", text="")
1126         col.label(text="Default Weight B:")
1127         col.prop(md, "default_weight_b", text="")
1128
1129         col.label(text="Mix Set:")
1130         col.prop(md, "mix_set", text="")
1131
1132         # Common mask options
1133         layout.separator()
1134         self.vertex_weight_mask(layout, ob, md)
1135
1136     def VERTEX_WEIGHT_PROXIMITY(self, layout, ob, md):
1137         split = layout.split()
1138
1139         col = split.column()
1140         col.label(text="Vertex Group:")
1141         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1142
1143         col = split.column()
1144         col.label(text="Target Object:")
1145         col.prop(md, "target", text="")
1146
1147         split = layout.split()
1148
1149         col = split.column()
1150         col.label(text="Distance:")
1151         col.prop(md, "proximity_mode", text="")
1152         if md.proximity_mode == 'GEOMETRY':
1153             col.row().prop(md, "proximity_geometry")
1154
1155         col = split.column()
1156         col.label()
1157         col.prop(md, "min_dist")
1158         col.prop(md, "max_dist")
1159
1160         layout.separator()
1161         layout.prop(md, "falloff_type")
1162
1163         # Common mask options
1164         layout.separator()
1165         self.vertex_weight_mask(layout, ob, md)
1166
1167     def SKIN(self, layout, ob, md):
1168         row = layout.row()
1169         row.operator("object.skin_armature_create", text="Create Armature")
1170         row.operator("mesh.customdata_skin_add")
1171
1172         layout.separator()
1173
1174         row = layout.row(align=True)
1175         row.prop(md, "branch_smoothing")
1176         row.prop(md, "use_smooth_shade")
1177
1178         split = layout.split()
1179
1180         col = split.column()
1181         col.label(text="Selected Vertices:")
1182         sub = col.column(align=True)
1183         sub.operator("object.skin_loose_mark_clear", text="Mark Loose").action = 'MARK'
1184         sub.operator("object.skin_loose_mark_clear", text="Clear Loose").action = 'CLEAR'
1185
1186         sub = col.column()
1187         sub.operator("object.skin_root_mark", text="Mark Root")
1188         sub.operator("object.skin_radii_equalize", text="Equalize Radii")
1189
1190         col = split.column()
1191         col.label(text="Symmetry Axes:")
1192         col.prop(md, "use_x_symmetry")
1193         col.prop(md, "use_y_symmetry")
1194         col.prop(md, "use_z_symmetry")
1195
1196     def TRIANGULATE(self, layout, ob, md):
1197         row = layout.row()
1198
1199         col = row.column()
1200         col.label(text="Quad Method:")
1201         col.prop(md, "quad_method", text="")
1202         col = row.column()
1203         col.label(text="Ngon Method:")
1204         col.prop(md, "ngon_method", text="")
1205
1206     def UV_WARP(self, layout, ob, md):
1207         split = layout.split()
1208         col = split.column()
1209         col.prop(md, "center")
1210
1211         col = split.column()
1212         col.label(text="UV Axis:")
1213         col.prop(md, "axis_u", text="")
1214         col.prop(md, "axis_v", text="")
1215
1216         split = layout.split()
1217         col = split.column()
1218         col.label(text="From:")
1219         col.prop(md, "object_from", text="")
1220
1221         col = split.column()
1222         col.label(text="To:")
1223         col.prop(md, "object_to", text="")
1224
1225         split = layout.split()
1226         col = split.column()
1227         obj = md.object_from
1228         if obj and obj.type == 'ARMATURE':
1229             col.label(text="Bone:")
1230             col.prop_search(md, "bone_from", obj.data, "bones", text="")
1231
1232         col = split.column()
1233         obj = md.object_to
1234         if obj and obj.type == 'ARMATURE':
1235             col.label(text="Bone:")
1236             col.prop_search(md, "bone_to", obj.data, "bones", text="")
1237
1238         split = layout.split()
1239
1240         col = split.column()
1241         col.label(text="Vertex Group:")
1242         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1243
1244         col = split.column()
1245         col.label(text="UV Map:")
1246         col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="")
1247
1248     def WIREFRAME(self, layout, ob, md):
1249         has_vgroup = bool(md.vertex_group)
1250
1251         split = layout.split()
1252
1253         col = split.column()
1254         col.prop(md, "thickness", text="Thickness")
1255
1256         row = col.row(align=True)
1257         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1258         sub = row.row(align=True)
1259         sub.active = has_vgroup
1260         sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
1261         row = col.row(align=True)
1262         row.active = has_vgroup
1263         row.prop(md, "thickness_vertex_group", text="Factor")
1264
1265         col.prop(md, "use_crease", text="Crease Edges")
1266         col.prop(md, "crease_weight", text="Crease Weight")
1267
1268         col = split.column()
1269
1270         col.prop(md, "offset")
1271         col.prop(md, "use_even_offset", text="Even Thickness")
1272         col.prop(md, "use_relative_offset", text="Relative Thickness")
1273         col.prop(md, "use_boundary", text="Boundary")
1274         col.prop(md, "use_replace", text="Replace Original")
1275
1276         col.prop(md, "material_offset", text="Material Offset")
1277
1278     def DATA_TRANSFER(self, layout, ob, md):
1279         row = layout.row(align=True)
1280         row.prop(md, "object")
1281         sub = row.row(align=True)
1282         sub.active = bool(md.object)
1283         sub.prop(md, "use_object_transform", text="", icon='GROUP')
1284
1285         layout.separator()
1286
1287         split = layout.split(0.333)
1288         split.prop(md, "use_vert_data")
1289         use_vert = md.use_vert_data
1290         row = split.row()
1291         row.active = use_vert
1292         row.prop(md, "vert_mapping", text="")
1293         if use_vert:
1294             col = layout.column(align=True)
1295             split = col.split(0.333, align=True)
1296             sub = split.column(align=True)
1297             sub.prop(md, "data_types_verts")
1298             sub = split.column(align=True)
1299             row = sub.row(align=True)
1300             row.prop(md, "layers_vgroup_select_src", text="")
1301             row.label(icon='RIGHTARROW')
1302             row.prop(md, "layers_vgroup_select_dst", text="")
1303             row = sub.row(align=True)
1304             row.label("", icon='NONE')
1305
1306         layout.separator()
1307
1308         split = layout.split(0.333)
1309         split.prop(md, "use_edge_data")
1310         use_edge = md.use_edge_data
1311         row = split.row()
1312         row.active = use_edge
1313         row.prop(md, "edge_mapping", text="")
1314         if use_edge:
1315             col = layout.column(align=True)
1316             split = col.split(0.333, align=True)
1317             sub = split.column(align=True)
1318             sub.prop(md, "data_types_edges")
1319
1320         layout.separator()
1321
1322         split = layout.split(0.333)
1323         split.prop(md, "use_loop_data")
1324         use_loop = md.use_loop_data
1325         row = split.row()
1326         row.active = use_loop
1327         row.prop(md, "loop_mapping", text="")
1328         if use_loop:
1329             col = layout.column(align=True)
1330             split = col.split(0.333, align=True)
1331             sub = split.column(align=True)
1332             sub.prop(md, "data_types_loops")
1333             sub = split.column(align=True)
1334             row = sub.row(align=True)
1335             row.label("", icon='NONE')
1336             row = sub.row(align=True)
1337             row.prop(md, "layers_vcol_select_src", text="")
1338             row.label(icon='RIGHTARROW')
1339             row.prop(md, "layers_vcol_select_dst", text="")
1340             row = sub.row(align=True)
1341             row.prop(md, "layers_uv_select_src", text="")
1342             row.label(icon='RIGHTARROW')
1343             row.prop(md, "layers_uv_select_dst", text="")
1344             col.prop(md, "islands_precision")
1345
1346         layout.separator()
1347
1348         split = layout.split(0.333)
1349         split.prop(md, "use_poly_data")
1350         use_poly = md.use_poly_data
1351         row = split.row()
1352         row.active = use_poly
1353         row.prop(md, "poly_mapping", text="")
1354         if use_poly:
1355             col = layout.column(align=True)
1356             split = col.split(0.333, align=True)
1357             sub = split.column(align=True)
1358             sub.prop(md, "data_types_polys")
1359
1360         layout.separator()
1361
1362         split = layout.split()
1363         col = split.column()
1364         row = col.row(align=True)
1365         sub = row.row(align=True)
1366         sub.active = md.use_max_distance
1367         sub.prop(md, "max_distance")
1368         row.prop(md, "use_max_distance", text="", icon='STYLUS_PRESSURE')
1369
1370         col = split.column()
1371         col.prop(md, "ray_radius")
1372
1373         layout.separator()
1374
1375         split = layout.split()
1376         col = split.column()
1377         col.prop(md, "mix_mode")
1378         col.prop(md, "mix_factor")
1379
1380         col = split.column()
1381         row = col.row()
1382         row.active = bool(md.object)
1383         row.operator("object.datalayout_transfer", text="Generate Data Layers")
1384         row = col.row(align=True)
1385         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1386         sub = row.row(align=True)
1387         sub.active = bool(md.vertex_group)
1388         sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
1389
1390     def NORMAL_EDIT(self, layout, ob, md):
1391         has_vgroup = bool(md.vertex_group)
1392         needs_object_offset = (((md.mode == 'RADIAL') and not md.target) or
1393                                ((md.mode == 'DIRECTIONAL') and md.use_direction_parallel))
1394
1395         row = layout.row()
1396         row.prop(md, "mode", expand=True)
1397
1398         split = layout.split()
1399
1400         col = split.column()
1401         col.prop(md, "target", text="")
1402         sub = col.column(align=True)
1403         sub.active = needs_object_offset
1404         sub.prop(md, "offset")
1405         row = col.row(align=True)
1406
1407         col = split.column()
1408         row = col.row()
1409         row.active = (md.mode == 'DIRECTIONAL')
1410         row.prop(md, "use_direction_parallel")
1411
1412         subcol = col.column(align=True)
1413         subcol.label("Mix Mode:")
1414         subcol.prop(md, "mix_mode", text="")
1415         subcol.prop(md, "mix_factor")
1416         row = subcol.row(align=True)
1417         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1418         sub = row.row(align=True)
1419         sub.active = has_vgroup
1420         sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
1421
1422     def CORRECTIVE_SMOOTH(self, layout, ob, md):
1423         is_bind = md.is_bind
1424
1425         layout.prop(md, "factor", text="Factor")
1426         layout.prop(md, "iterations")
1427
1428         row = layout.row()
1429         row.prop(md, "smooth_type")
1430
1431         split = layout.split()
1432
1433         col = split.column()
1434         col.label(text="Vertex Group:")
1435         row = col.row(align=True)
1436         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1437         row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
1438
1439         col = split.column()
1440         col.prop(md, "use_only_smooth")
1441         col.prop(md, "use_pin_boundary")
1442
1443         layout.prop(md, "rest_source")
1444         if md.rest_source == 'BIND':
1445             layout.operator("object.correctivesmooth_bind", text="Unbind" if is_bind else "Bind")
1446
1447
1448 if __name__ == "__main__":  # only for live edit.
1449     bpy.utils.register_module(__name__)