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