1 # ##### BEGIN GPL LICENSE BLOCK #####
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.
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.
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.
17 # ##### END GPL LICENSE BLOCK #####
21 from bpy.types import Panel
24 class ModifierButtonsPanel():
25 bl_space_type = 'PROPERTIES'
26 bl_region_type = 'WINDOW'
27 bl_context = "modifier"
30 class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
31 bl_label = "Modifiers"
33 def draw(self, context):
38 layout.operator_menu_enum("object.modifier_add", "type")
40 for md in ob.modifiers:
41 box = layout.template_modifier(md)
43 # match enum type to our functions, avoids a lookup table.
44 getattr(self, md.type)(box, ob, md)
46 # the mt.type enum is (ab)used for a lookup on function names
47 # ...to avoid lengthy if statements
48 # so each type must have a function here.
50 def NGONINTERP(self, layout, ob, md):
51 split = layout.split()
52 split.prop(md, "resolution")
54 def ARMATURE(self, layout, ob, md):
55 split = layout.split()
58 col.label(text="Object:")
59 col.prop(md, "object", text="")
60 col.prop(md, "use_deform_preserve_volume")
63 col.label(text="Bind To:")
64 col.prop(md, "use_vertex_groups", text="Vertex Groups")
65 col.prop(md, "use_bone_envelopes", text="Bone Envelopes")
70 row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
72 sub.active = bool(md.vertex_group)
73 sub.prop(md, "invert_vertex_group")
75 layout.prop(md, "use_multi_modifier")
77 def ARRAY(self, layout, ob, md):
78 layout.prop(md, "fit_type")
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")
89 split = layout.split()
92 col.prop(md, "use_constant_offset")
94 sub.active = md.use_constant_offset
95 sub.prop(md, "constant_offset_displace", text="")
99 col.prop(md, "use_merge_vertices", text="Merge")
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")
106 col.prop(md, "use_relative_offset")
108 sub.active = md.use_relative_offset
109 sub.prop(md, "relative_offset_displace", text="")
113 col.prop(md, "use_object_offset")
115 sub.active = md.use_object_offset
116 sub.prop(md, "offset_object", text="")
120 layout.prop(md, "start_cap")
121 layout.prop(md, "end_cap")
123 def BEVEL(self, layout, ob, md):
124 split = layout.split()
126 split.prop(md, "width")
127 split.prop(md, "use_only_vertices")
129 layout.label(text="Limit Method:")
130 layout.row().prop(md, "limit_method", expand=True)
131 if md.limit_method == 'ANGLE':
132 layout.prop(md, "angle_limit")
133 elif md.limit_method == 'WEIGHT':
134 layout.row().prop(md, "edge_weight_method", expand=True)
136 def BOOLEAN(self, layout, ob, md):
137 split = layout.split()
140 col.label(text="Operation:")
141 col.prop(md, "operation", text="")
144 col.label(text="Object:")
145 col.prop(md, "object", text="")
147 def BUILD(self, layout, ob, md):
148 split = layout.split()
151 col.prop(md, "frame_start")
152 col.prop(md, "frame_duration")
155 col.prop(md, "use_random_order")
157 sub.active = md.use_random_order
160 def CAST(self, layout, ob, md):
161 split = layout.split(percentage=0.25)
163 split.label(text="Cast Type:")
164 split.prop(md, "cast_type", text="")
166 split = layout.split(percentage=0.25)
169 col.prop(md, "use_x")
170 col.prop(md, "use_y")
171 col.prop(md, "use_z")
174 col.prop(md, "factor")
175 col.prop(md, "radius")
177 col.prop(md, "use_radius_as_size")
179 split = layout.split()
182 col.label(text="Vertex Group:")
183 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
185 col.label(text="Control Object:")
186 col.prop(md, "object", text="")
188 col.prop(md, "use_transform")
190 def CLOTH(self, layout, ob, md):
191 layout.label(text="Settings can be found inside the Physics context")
193 def COLLISION(self, layout, ob, md):
194 layout.label(text="Settings can be found inside the Physics context")
196 def CURVE(self, layout, ob, md):
197 split = layout.split()
200 col.label(text="Object:")
201 col.prop(md, "object", text="")
203 col.label(text="Vertex Group:")
204 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
205 layout.label(text="Deformation Axis:")
206 layout.row().prop(md, "deform_axis", expand=True)
208 def DECIMATE(self, layout, ob, md):
209 layout.prop(md, "ratio")
210 layout.label(text="Face Count: %s" % str(md.face_count))
212 def DISPLACE(self, layout, ob, md):
213 split = layout.split()
216 col.label(text="Texture:")
217 col.template_ID(md, "texture", new="texture.new")
218 col.label(text="Vertex Group:")
219 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
222 col.label(text="Direction:")
223 col.prop(md, "direction", text="")
224 col.label(text="Texture Coordinates:")
225 col.prop(md, "texture_coords", text="")
226 if md.texture_coords == 'OBJECT':
227 layout.prop(md, "texture_coords_object", text="Object")
228 elif md.texture_coords == 'UV' and ob.type == 'MESH':
229 layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
234 row.prop(md, "mid_level")
235 row.prop(md, "strength")
237 def EDGE_SPLIT(self, layout, ob, md):
238 split = layout.split()
241 col.prop(md, "use_edge_angle", text="Edge Angle")
243 sub.active = md.use_edge_angle
244 sub.prop(md, "split_angle")
246 split.prop(md, "use_edge_sharp", text="Sharp Edges")
248 def EXPLODE(self, layout, ob, md):
249 split = layout.split()
252 col.label(text="Vertex group:")
253 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
255 sub.active = bool(md.vertex_group)
256 sub.prop(md, "protect")
257 col.label(text="Particle UV")
258 col.prop_search(md, "particle_uv", ob.data, "uv_textures", text="")
261 col.prop(md, "use_edge_cut")
262 col.prop(md, "show_unborn")
263 col.prop(md, "show_alive")
264 col.prop(md, "show_dead")
265 col.prop(md, "use_size")
267 layout.operator("object.explode_refresh", text="Refresh")
269 def FLUID_SIMULATION(self, layout, ob, md):
270 layout.label(text="Settings can be found inside the Physics context")
272 def HOOK(self, layout, ob, md):
273 split = layout.split()
276 col.label(text="Object:")
277 col.prop(md, "object", text="")
278 if md.object and md.object.type == 'ARMATURE':
279 col.label(text="Bone:")
280 col.prop_search(md, "subtarget", md.object.data, "bones", text="")
282 col.label(text="Vertex Group:")
283 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
287 split = layout.split()
290 col.prop(md, "falloff")
291 col.prop(md, "force", slider=True)
294 col.operator("object.hook_reset", text="Reset")
295 col.operator("object.hook_recenter", text="Recenter")
297 if ob.mode == 'EDIT':
300 row.operator("object.hook_select", text="Select")
301 row.operator("object.hook_assign", text="Assign")
303 def LATTICE(self, layout, ob, md):
304 split = layout.split()
307 col.label(text="Object:")
308 col.prop(md, "object", text="")
311 col.label(text="Vertex Group:")
312 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
314 def MASK(self, layout, ob, md):
315 split = layout.split()
318 col.label(text="Mode:")
319 col.prop(md, "mode", text="")
321 if md.mode == 'ARMATURE':
322 col.label(text="Armature:")
323 col.prop(md, "armature", text="")
324 elif md.mode == 'VERTEX_GROUP':
325 col.label(text="Vertex Group:")
326 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
329 sub.active = bool(md.vertex_group)
330 sub.prop(md, "invert_vertex_group")
332 def MESH_DEFORM(self, layout, ob, md):
333 split = layout.split()
337 sub.label(text="Object:")
338 sub.prop(md, "object", text="")
339 sub.active = not md.is_bound
341 col.label(text="Vertex Group:")
342 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
345 sub.active = bool(md.vertex_group)
346 sub.prop(md, "invert_vertex_group")
351 layout.operator("object.meshdeform_bind", text="Unbind")
353 layout.operator("object.meshdeform_bind", text="Bind")
356 row.prop(md, "precision")
357 row.prop(md, "use_dynamic_bind")
359 def MIRROR(self, layout, ob, md):
360 split = layout.split(percentage=0.25)
363 col.label(text="Axis:")
364 col.prop(md, "use_x")
365 col.prop(md, "use_y")
366 col.prop(md, "use_z")
369 col.label(text="Options:")
370 col.prop(md, "use_mirror_merge", text="Merge")
371 col.prop(md, "use_clip", text="Clipping")
372 col.prop(md, "use_mirror_vertex_groups", text="Vertex Groups")
375 col.label(text="Textures:")
376 col.prop(md, "use_mirror_u", text="U")
377 col.prop(md, "use_mirror_v", text="V")
379 col = layout.column()
381 if md.use_mirror_merge == True:
382 col.prop(md, "merge_threshold")
383 col.label(text="Mirror Object:")
384 col.prop(md, "mirror_object", text="")
386 def MULTIRES(self, layout, ob, md):
387 layout.row().prop(md, "subdivision_type", expand=True)
389 split = layout.split()
391 col.prop(md, "levels", text="Preview")
392 col.prop(md, "sculpt_levels", text="Sculpt")
393 col.prop(md, "render_levels", text="Render")
397 col.enabled = ob.mode != 'EDIT'
398 col.operator("object.multires_subdivide", text="Subdivide")
399 col.operator("object.multires_higher_levels_delete", text="Delete Higher")
400 col.operator("object.multires_reshape", text="Reshape")
401 col.operator("object.multires_base_apply", text="Apply Base")
402 col.prop(md, "use_subsurf_uv")
403 col.prop(md, "show_only_control_edges")
407 col = layout.column()
410 row.operator("object.multires_external_pack", text="Pack External")
413 row.prop(md, "filepath", text="")
415 row.operator("object.multires_external_save", text="Save External...")
418 def PARTICLE_INSTANCE(self, layout, ob, md):
419 layout.prop(md, "object")
420 layout.prop(md, "particle_system_index", text="Particle System")
422 split = layout.split()
424 col.label(text="Create From:")
425 col.prop(md, "use_normal")
426 col.prop(md, "use_children")
427 col.prop(md, "use_size")
430 col.label(text="Show Particles When:")
431 col.prop(md, "show_alive")
432 col.prop(md, "show_unborn")
433 col.prop(md, "show_dead")
437 layout.prop(md, "use_path", text="Create Along Paths")
439 split = layout.split()
440 split.active = md.use_path
442 col.row().prop(md, "axis", expand=True)
443 col.prop(md, "use_preserve_shape")
446 col.prop(md, "position", slider=True)
447 col.prop(md, "random_position", text="Random", slider=True)
449 def PARTICLE_SYSTEM(self, layout, ob, md):
450 layout.label(text="Settings can be found inside the Particle context")
452 def SCREW(self, layout, ob, md):
453 split = layout.split()
457 col.prop(md, "object", text="AxisOb")
458 col.prop(md, "angle")
459 col.prop(md, "steps")
460 col.prop(md, "render_steps")
464 row.active = (md.object is None or md.use_object_screw_offset == False)
465 row.prop(md, "screw_offset")
467 row.active = (md.object is not None)
468 row.prop(md, "use_object_screw_offset")
469 col.prop(md, "use_normal_calculate")
470 col.prop(md, "use_normal_flip")
471 col.prop(md, "iterations")
473 def SHRINKWRAP(self, layout, ob, md):
474 split = layout.split()
476 col.label(text="Target:")
477 col.prop(md, "target", text="")
479 col.label(text="Vertex Group:")
480 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
482 split = layout.split()
485 col.prop(md, "offset")
486 col.prop(md, "subsurf_levels")
489 col.label(text="Mode:")
490 col.prop(md, "wrap_method", text="")
492 if md.wrap_method == 'PROJECT':
493 split = layout.split(percentage=0.25)
496 col.label(text="Axis:")
497 col.prop(md, "use_project_x")
498 col.prop(md, "use_project_y")
499 col.prop(md, "use_project_z")
502 col.label(text="Direction:")
503 col.prop(md, "use_negative_direction")
504 col.prop(md, "use_positive_direction")
507 col.label(text="Cull Faces:")
508 col.prop(md, "cull_face", expand=True)
510 layout.label(text="Auxiliary Target:")
511 layout.prop(md, "auxiliary_target", text="")
513 elif md.wrap_method == 'NEAREST_SURFACEPOINT':
514 layout.prop(md, "use_keep_above_surface")
516 def SIMPLE_DEFORM(self, layout, ob, md):
517 split = layout.split()
520 col.label(text="Mode:")
521 col.prop(md, "deform_method", text="")
524 col.label(text="Vertex Group:")
525 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
527 split = layout.split()
530 col.label(text="Origin:")
531 col.prop(md, "origin", text="")
533 sub.active = (md.origin is not None)
534 sub.prop(md, "use_relative")
537 col.label(text="Deform:")
538 col.prop(md, "factor")
539 col.prop(md, "limits", slider=True)
540 if md.deform_method in {'TAPER', 'STRETCH'}:
541 col.prop(md, "lock_x")
542 col.prop(md, "lock_y")
544 def SMOKE(self, layout, ob, md):
545 layout.label(text="Settings can be found inside the Physics context")
547 def SMOOTH(self, layout, ob, md):
548 split = layout.split(percentage=0.25)
551 col.label(text="Axis:")
552 col.prop(md, "use_x")
553 col.prop(md, "use_y")
554 col.prop(md, "use_z")
557 col.prop(md, "factor")
558 col.prop(md, "iterations")
559 col.label(text="Vertex Group:")
560 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
562 def SOFT_BODY(self, layout, ob, md):
563 layout.label(text="Settings can be found inside the Physics context")
565 def SOLIDIFY(self, layout, ob, md):
566 split = layout.split()
569 col.prop(md, "thickness")
570 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
572 col.label(text="Crease:")
573 col.prop(md, "edge_crease_inner", text="Inner")
574 col.prop(md, "edge_crease_outer", text="Outer")
575 col.prop(md, "edge_crease_rim", text="Rim")
576 col.label(text="Material Index Offset:")
580 col.prop(md, "offset")
582 sub.active = bool(md.vertex_group)
583 sub.prop(md, "invert_vertex_group", text="Invert")
584 sub.prop(md, "thickness_vertex_group", text="Factor")
586 col.prop(md, "use_even_offset")
587 col.prop(md, "use_quality_normals")
588 col.prop(md, "use_rim")
591 row = sub.split(align=True, percentage=0.4)
592 row.prop(md, "material_offset", text="")
594 row.active = md.use_rim
595 row.prop(md, "material_offset_rim", text="Rim")
597 def SUBSURF(self, layout, ob, md):
598 layout.row().prop(md, "subdivision_type", expand=True)
600 split = layout.split()
602 col.label(text="Subdivisions:")
603 col.prop(md, "levels", text="View")
604 col.prop(md, "render_levels", text="Render")
607 col.label(text="Options:")
608 col.prop(md, "use_subsurf_uv")
609 col.prop(md, "show_only_control_edges")
611 def SURFACE(self, layout, ob, md):
612 layout.label(text="Settings can be found inside the Physics context")
614 def UV_PROJECT(self, layout, ob, md):
615 split = layout.split()
618 col.label(text="Image:")
619 col.prop(md, "image", text="")
622 col.label(text="UV Layer:")
623 col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="")
625 split = layout.split()
627 col.prop(md, "use_image_override")
628 col.prop(md, "projector_count", text="Projectors")
629 for proj in md.projectors:
630 col.prop(proj, "object", text="")
633 sub = col.column(align=True)
634 sub.prop(md, "aspect_x", text="Aspect X")
635 sub.prop(md, "aspect_y", text="Aspect Y")
637 sub = col.column(align=True)
638 sub.prop(md, "scale_x", text="Scale X")
639 sub.prop(md, "scale_y", text="Scale Y")
641 def WARP(self, layout, ob, md):
642 use_falloff = (md.falloff_type != 'NONE')
643 split = layout.split()
646 col.label(text="From:")
647 col.prop(md, "object_from", text="")
649 col.prop(md, "use_volume_preserve")
652 col.label(text="To:")
653 col.prop(md, "object_to", text="")
654 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
656 col = layout.column()
658 row = col.row(align=True)
659 row.prop(md, "strength")
661 row.prop(md, "falloff_radius")
663 col.prop(md, "falloff_type")
665 if md.falloff_type == 'CURVE':
666 col.template_curve_mapping(md, "falloff_curve")
669 split = layout.split()
671 col.label(text="Texture:")
672 col.prop(md, "texture", text="")
675 col.label(text="Texture Coordinates:")
676 col.prop(md, "texture_coords", text="")
678 if md.texture_coords == 'OBJECT':
679 layout.prop(md, "texture_coords_object", text="Object")
680 elif md.texture_coords == 'UV' and ob.type == 'MESH':
681 layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
683 def WAVE(self, layout, ob, md):
684 split = layout.split()
687 col.label(text="Motion:")
688 col.prop(md, "use_x")
689 col.prop(md, "use_y")
690 col.prop(md, "use_cyclic")
693 col.prop(md, "use_normal")
695 sub.active = md.use_normal
696 sub.prop(md, "use_normal_x", text="X")
697 sub.prop(md, "use_normal_y", text="Y")
698 sub.prop(md, "use_normal_z", text="Z")
700 split = layout.split()
703 col.label(text="Time:")
704 sub = col.column(align=True)
705 sub.prop(md, "time_offset", text="Offset")
706 sub.prop(md, "lifetime", text="Life")
707 col.prop(md, "damping_time", text="Damping")
710 col.label(text="Position:")
711 sub = col.column(align=True)
712 sub.prop(md, "start_position_x", text="X")
713 sub.prop(md, "start_position_y", text="Y")
714 col.prop(md, "falloff_radius", text="Falloff")
718 layout.prop(md, "start_position_object")
719 layout.prop_search(md, "vertex_group", ob, "vertex_groups")
720 split = layout.split(percentage=0.33)
722 col.label(text="Texture")
724 col.template_ID(md, "texture", new="texture.new")
725 layout.prop(md, "texture_coords")
726 if md.texture_coords == 'MAP_UV' and ob.type == 'MESH':
727 layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
728 elif md.texture_coords == 'OBJECT':
729 layout.prop(md, "texture_coords_object")
733 split = layout.split()
736 col.prop(md, "speed", slider=True)
737 col.prop(md, "height", slider=True)
740 col.prop(md, "width", slider=True)
741 col.prop(md, "narrowness", slider=True)
744 def vertex_weight_mask(layout, ob, md):
745 layout.label(text="Influence/Mask Options:")
747 split = layout.split(percentage=0.4)
748 split.label(text="Global Influence:")
749 split.prop(md, "mask_constant", text="")
751 if not md.mask_texture:
752 split = layout.split(percentage=0.4)
753 split.label(text="Vertex Group Mask:")
754 split.prop_search(md, "mask_vertex_group", ob, "vertex_groups", text="")
756 if not md.mask_vertex_group:
757 split = layout.split(percentage=0.4)
758 split.label(text="Texture Mask:")
759 split.template_ID(md, "mask_texture", new="texture.new")
761 split = layout.split()
764 col.label(text="Texture Coordinates:")
765 col.prop(md, "mask_tex_mapping", text="")
768 col.label(text="Use Channel:")
769 col.prop(md, "mask_tex_use_channel", text="")
771 if md.mask_tex_mapping == 'OBJECT':
772 layout.prop(md, "mask_tex_map_object", text="Object")
773 elif md.mask_tex_mapping == 'UV' and ob.type == 'MESH':
774 layout.prop_search(md, "mask_tex_uv_layer", ob.data, "uv_textures")
776 def VERTEX_WEIGHT_EDIT(self, layout, ob, md):
777 split = layout.split()
779 col.label(text="Vertex Group:")
780 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
783 col.label(text="Default Weight:")
784 col.prop(md, "default_weight", text="")
786 layout.prop(md, "falloff_type")
787 if md.falloff_type == 'CURVE':
788 col = layout.column()
789 col.template_curve_mapping(md, "map_curve")
791 split = layout.split(percentage=0.4)
792 split.prop(md, "use_add")
794 row.active = md.use_add
795 row.prop(md, "add_threshold")
797 split = layout.split(percentage=0.4)
798 split.prop(md, "use_remove")
800 row.active = md.use_remove
801 row.prop(md, "remove_threshold")
803 # Common mask options
805 self.vertex_weight_mask(layout, ob, md)
807 def VERTEX_WEIGHT_MIX(self, layout, ob, md):
808 split = layout.split()
811 col.label(text="Vertex Group A:")
812 col.prop_search(md, "vertex_group_a", ob, "vertex_groups", text="")
813 col.label(text="Default Weight A:")
814 col.prop(md, "default_weight_a", text="")
816 col.label(text="Mix Mode:")
817 col.prop(md, "mix_mode", text="")
820 col.label(text="Vertex Group B:")
821 col.prop_search(md, "vertex_group_b", ob, "vertex_groups", text="")
822 col.label(text="Default Weight B:")
823 col.prop(md, "default_weight_b", text="")
825 col.label(text="Mix Set:")
826 col.prop(md, "mix_set", text="")
828 # Common mask options
830 self.vertex_weight_mask(layout, ob, md)
832 def VERTEX_WEIGHT_PROXIMITY(self, layout, ob, md):
833 split = layout.split()
836 col.label(text="Vertex Group:")
837 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
840 col.label(text="Target Object:")
841 col.prop(md, "target", text="")
843 layout.row().prop(md, "proximity_mode", expand=True)
844 if md.proximity_mode == 'GEOMETRY':
845 layout.row().prop(md, "proximity_geometry", expand=True)
848 row.prop(md, "min_dist")
849 row.prop(md, "max_dist")
851 layout.prop(md, "falloff_type")
853 # Common mask options
855 self.vertex_weight_mask(layout, ob, md)
857 if __name__ == "__main__": # only for live edit.
858 bpy.utils.register_module(__name__)