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 ARMATURE(self, layout, ob, md):
51 split = layout.split()
54 col.label(text="Object:")
55 col.prop(md, "object", text="")
56 col.prop(md, "use_deform_preserve_volume")
59 col.label(text="Bind To:")
60 col.prop(md, "use_vertex_groups", text="Vertex Groups")
61 col.prop(md, "use_bone_envelopes", text="Bone Envelopes")
66 row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
68 sub.active = bool(md.vertex_group)
69 sub.prop(md, "invert_vertex_group")
71 layout.prop(md, "use_multi_modifier")
73 def ARRAY(self, layout, ob, md):
74 layout.prop(md, "fit_type")
76 if md.fit_type == 'FIXED_COUNT':
77 layout.prop(md, "count")
78 elif md.fit_type == 'FIT_LENGTH':
79 layout.prop(md, "fit_length")
80 elif md.fit_type == 'FIT_CURVE':
81 layout.prop(md, "curve")
85 split = layout.split()
88 col.prop(md, "use_constant_offset")
90 sub.active = md.use_constant_offset
91 sub.prop(md, "constant_offset_displace", text="")
95 col.prop(md, "use_merge_vertices", text="Merge")
97 sub.active = md.use_merge_vertices
98 sub.prop(md, "use_merge_vertices_cap", text="First Last")
99 sub.prop(md, "merge_threshold", text="Distance")
102 col.prop(md, "use_relative_offset")
104 sub.active = md.use_relative_offset
105 sub.prop(md, "relative_offset_displace", text="")
109 col.prop(md, "use_object_offset")
111 sub.active = md.use_object_offset
112 sub.prop(md, "offset_object", text="")
116 layout.prop(md, "start_cap")
117 layout.prop(md, "end_cap")
119 def BEVEL(self, layout, ob, md):
120 split = layout.split()
122 split.prop(md, "width")
123 split.prop(md, "use_only_vertices")
125 layout.label(text="Limit Method:")
126 layout.row().prop(md, "limit_method", expand=True)
127 if md.limit_method == 'ANGLE':
128 layout.prop(md, "angle_limit")
129 elif md.limit_method == 'WEIGHT':
130 layout.row().prop(md, "edge_weight_method", expand=True)
132 def BOOLEAN(self, layout, ob, md):
133 split = layout.split()
136 col.label(text="Operation:")
137 col.prop(md, "operation", text="")
140 col.label(text="Object:")
141 col.prop(md, "object", text="")
143 def BUILD(self, layout, ob, md):
144 split = layout.split()
147 col.prop(md, "frame_start")
148 col.prop(md, "frame_duration")
151 col.prop(md, "use_random_order")
153 sub.active = md.use_random_order
156 def CAST(self, layout, ob, md):
157 split = layout.split(percentage=0.25)
159 split.label(text="Cast Type:")
160 split.prop(md, "cast_type", text="")
162 split = layout.split(percentage=0.25)
165 col.prop(md, "use_x")
166 col.prop(md, "use_y")
167 col.prop(md, "use_z")
170 col.prop(md, "factor")
171 col.prop(md, "radius")
173 col.prop(md, "use_radius_as_size")
175 split = layout.split()
178 col.label(text="Vertex Group:")
179 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
181 col.label(text="Control Object:")
182 col.prop(md, "object", text="")
184 col.prop(md, "use_transform")
186 def CLOTH(self, layout, ob, md):
187 layout.label(text="Settings can be found inside the Physics context")
189 def COLLISION(self, layout, ob, md):
190 layout.label(text="Settings can be found inside the Physics context")
192 def CURVE(self, layout, ob, md):
193 split = layout.split()
196 col.label(text="Object:")
197 col.prop(md, "object", text="")
199 col.label(text="Vertex Group:")
200 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
201 layout.label(text="Deformation Axis:")
202 layout.row().prop(md, "deform_axis", expand=True)
204 def DECIMATE(self, layout, ob, md):
205 layout.prop(md, "ratio")
206 layout.label(text="Face Count" + ": %d" % md.face_count)
208 def DISPLACE(self, layout, ob, md):
209 split = layout.split()
212 col.label(text="Texture:")
213 col.template_ID(md, "texture", new="texture.new")
214 col.label(text="Vertex Group:")
215 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
218 col.label(text="Direction:")
219 col.prop(md, "direction", text="")
220 col.label(text="Texture Coordinates:")
221 col.prop(md, "texture_coords", text="")
222 if md.texture_coords == 'OBJECT':
223 layout.prop(md, "texture_coords_object", text="Object")
224 elif md.texture_coords == 'UV' and ob.type == 'MESH':
225 layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
230 row.prop(md, "mid_level")
231 row.prop(md, "strength")
233 def DYNAMIC_PAINT(self, layout, ob, md):
234 layout.label(text="See Dynamic Paint panel.")
236 def EDGE_SPLIT(self, layout, ob, md):
237 split = layout.split()
240 col.prop(md, "use_edge_angle", text="Edge Angle")
242 sub.active = md.use_edge_angle
243 sub.prop(md, "split_angle")
245 split.prop(md, "use_edge_sharp", text="Sharp Edges")
247 def EXPLODE(self, layout, ob, md):
248 split = layout.split()
251 col.label(text="Vertex group:")
252 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
254 sub.active = bool(md.vertex_group)
255 sub.prop(md, "protect")
256 col.label(text="Particle UV")
257 col.prop_search(md, "particle_uv", ob.data, "uv_textures", text="")
260 col.prop(md, "use_edge_cut")
261 col.prop(md, "show_unborn")
262 col.prop(md, "show_alive")
263 col.prop(md, "show_dead")
264 col.prop(md, "use_size")
266 layout.operator("object.explode_refresh", text="Refresh")
268 def FLUID_SIMULATION(self, layout, ob, md):
269 layout.label(text="Settings can be found inside the Physics context")
271 def HOOK(self, layout, ob, md):
272 split = layout.split()
275 col.label(text="Object:")
276 col.prop(md, "object", text="")
277 if md.object and md.object.type == 'ARMATURE':
278 col.label(text="Bone:")
279 col.prop_search(md, "subtarget", md.object.data, "bones", text="")
281 col.label(text="Vertex Group:")
282 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
286 split = layout.split()
289 col.prop(md, "falloff")
290 col.prop(md, "force", slider=True)
293 col.operator("object.hook_reset", text="Reset")
294 col.operator("object.hook_recenter", text="Recenter")
296 if ob.mode == 'EDIT':
299 row.operator("object.hook_select", text="Select")
300 row.operator("object.hook_assign", text="Assign")
302 def LATTICE(self, layout, ob, md):
303 split = layout.split()
306 col.label(text="Object:")
307 col.prop(md, "object", text="")
310 col.label(text="Vertex Group:")
311 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
313 def MASK(self, layout, ob, md):
314 split = layout.split()
317 col.label(text="Mode:")
318 col.prop(md, "mode", text="")
320 if md.mode == 'ARMATURE':
321 col.label(text="Armature:")
322 col.prop(md, "armature", text="")
323 elif md.mode == 'VERTEX_GROUP':
324 col.label(text="Vertex Group:")
325 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
328 sub.active = bool(md.vertex_group)
329 sub.prop(md, "invert_vertex_group")
331 def MESH_DEFORM(self, layout, ob, md):
332 split = layout.split()
336 sub.label(text="Object:")
337 sub.prop(md, "object", text="")
338 sub.active = not md.is_bound
340 col.label(text="Vertex Group:")
341 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
344 sub.active = bool(md.vertex_group)
345 sub.prop(md, "invert_vertex_group")
350 layout.operator("object.meshdeform_bind", text="Unbind")
352 layout.operator("object.meshdeform_bind", text="Bind")
355 row.prop(md, "precision")
356 row.prop(md, "use_dynamic_bind")
358 def MIRROR(self, layout, ob, md):
359 split = layout.split(percentage=0.25)
362 col.label(text="Axis:")
363 col.prop(md, "use_x")
364 col.prop(md, "use_y")
365 col.prop(md, "use_z")
368 col.label(text="Options:")
369 col.prop(md, "use_mirror_merge", text="Merge")
370 col.prop(md, "use_clip", text="Clipping")
371 col.prop(md, "use_mirror_vertex_groups", text="Vertex Groups")
374 col.label(text="Textures:")
375 col.prop(md, "use_mirror_u", text="U")
376 col.prop(md, "use_mirror_v", text="V")
378 col = layout.column()
380 if md.use_mirror_merge == True:
381 col.prop(md, "merge_threshold")
382 col.label(text="Mirror Object:")
383 col.prop(md, "mirror_object", text="")
385 def MULTIRES(self, layout, ob, md):
386 layout.row().prop(md, "subdivision_type", expand=True)
388 split = layout.split()
390 col.prop(md, "levels", text="Preview")
391 col.prop(md, "sculpt_levels", text="Sculpt")
392 col.prop(md, "render_levels", text="Render")
396 col.enabled = ob.mode != 'EDIT'
397 col.operator("object.multires_subdivide", text="Subdivide")
398 col.operator("object.multires_higher_levels_delete", text="Delete Higher")
399 col.operator("object.multires_reshape", text="Reshape")
400 col.operator("object.multires_base_apply", text="Apply Base")
401 col.prop(md, "use_subsurf_uv")
402 col.prop(md, "show_only_control_edges")
406 col = layout.column()
409 row.operator("object.multires_external_pack", text="Pack External")
412 row.prop(md, "filepath", text="")
414 row.operator("object.multires_external_save", text="Save External...")
417 def PARTICLE_INSTANCE(self, layout, ob, md):
418 layout.prop(md, "object")
419 layout.prop(md, "particle_system_index", text="Particle System")
421 split = layout.split()
423 col.label(text="Create From:")
424 col.prop(md, "use_normal")
425 col.prop(md, "use_children")
426 col.prop(md, "use_size")
429 col.label(text="Show Particles When:")
430 col.prop(md, "show_alive")
431 col.prop(md, "show_unborn")
432 col.prop(md, "show_dead")
436 layout.prop(md, "use_path", text="Create Along Paths")
438 split = layout.split()
439 split.active = md.use_path
441 col.row().prop(md, "axis", expand=True)
442 col.prop(md, "use_preserve_shape")
445 col.prop(md, "position", slider=True)
446 col.prop(md, "random_position", text="Random", slider=True)
448 def PARTICLE_SYSTEM(self, layout, ob, md):
449 layout.label(text="Settings can be found inside the Particle context")
451 def SCREW(self, layout, ob, md):
452 split = layout.split()
456 col.prop(md, "object", text="AxisOb")
457 col.prop(md, "angle")
458 col.prop(md, "steps")
459 col.prop(md, "render_steps")
463 row.active = (md.object is None or md.use_object_screw_offset == False)
464 row.prop(md, "screw_offset")
466 row.active = (md.object is not None)
467 row.prop(md, "use_object_screw_offset")
468 col.prop(md, "use_normal_calculate")
469 col.prop(md, "use_normal_flip")
470 col.prop(md, "iterations")
472 def SHRINKWRAP(self, layout, ob, md):
473 split = layout.split()
475 col.label(text="Target:")
476 col.prop(md, "target", text="")
478 col.label(text="Vertex Group:")
479 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
481 split = layout.split()
484 col.prop(md, "offset")
485 col.prop(md, "subsurf_levels")
488 col.label(text="Mode:")
489 col.prop(md, "wrap_method", text="")
491 if md.wrap_method == 'PROJECT':
492 split = layout.split(percentage=0.25)
495 col.label(text="Axis:")
496 col.prop(md, "use_project_x")
497 col.prop(md, "use_project_y")
498 col.prop(md, "use_project_z")
501 col.label(text="Direction:")
502 col.prop(md, "use_negative_direction")
503 col.prop(md, "use_positive_direction")
506 col.label(text="Cull Faces:")
507 col.prop(md, "cull_face", expand=True)
509 layout.label(text="Auxiliary Target:")
510 layout.prop(md, "auxiliary_target", text="")
512 elif md.wrap_method == 'NEAREST_SURFACEPOINT':
513 layout.prop(md, "use_keep_above_surface")
515 def SIMPLE_DEFORM(self, layout, ob, md):
516 split = layout.split()
519 col.label(text="Mode:")
520 col.prop(md, "deform_method", text="")
523 col.label(text="Vertex Group:")
524 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
526 split = layout.split()
529 col.label(text="Origin:")
530 col.prop(md, "origin", text="")
532 sub.active = (md.origin is not None)
533 sub.prop(md, "use_relative")
536 col.label(text="Deform:")
537 col.prop(md, "factor")
538 col.prop(md, "limits", slider=True)
539 if md.deform_method in {'TAPER', 'STRETCH'}:
540 col.prop(md, "lock_x")
541 col.prop(md, "lock_y")
543 def SMOKE(self, layout, ob, md):
544 layout.label(text="Settings can be found inside the Physics context")
546 def SMOOTH(self, layout, ob, md):
547 split = layout.split(percentage=0.25)
550 col.label(text="Axis:")
551 col.prop(md, "use_x")
552 col.prop(md, "use_y")
553 col.prop(md, "use_z")
556 col.prop(md, "factor")
557 col.prop(md, "iterations")
558 col.label(text="Vertex Group:")
559 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
561 def SOFT_BODY(self, layout, ob, md):
562 layout.label(text="Settings can be found inside the Physics context")
564 def SOLIDIFY(self, layout, ob, md):
565 split = layout.split()
568 col.prop(md, "thickness")
569 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
571 col.label(text="Crease:")
572 col.prop(md, "edge_crease_inner", text="Inner")
573 col.prop(md, "edge_crease_outer", text="Outer")
574 col.prop(md, "edge_crease_rim", text="Rim")
575 col.label(text="Material Index Offset:")
579 col.prop(md, "offset")
581 sub.active = bool(md.vertex_group)
582 sub.prop(md, "invert_vertex_group", text="Invert")
583 sub.prop(md, "thickness_vertex_group", text="Factor")
585 col.prop(md, "use_even_offset")
586 col.prop(md, "use_quality_normals")
587 col.prop(md, "use_rim")
590 row = sub.split(align=True, percentage=0.4)
591 row.prop(md, "material_offset", text="")
593 row.active = md.use_rim
594 row.prop(md, "material_offset_rim", text="Rim")
596 def SUBSURF(self, layout, ob, md):
597 layout.row().prop(md, "subdivision_type", expand=True)
599 split = layout.split()
601 col.label(text="Subdivisions:")
602 col.prop(md, "levels", text="View")
603 col.prop(md, "render_levels", text="Render")
606 col.label(text="Options:")
607 col.prop(md, "use_subsurf_uv")
608 col.prop(md, "show_only_control_edges")
610 def SURFACE(self, layout, ob, md):
611 layout.label(text="Settings can be found inside the Physics context")
613 def UV_PROJECT(self, layout, ob, md):
614 split = layout.split()
617 col.label(text="Image:")
618 col.prop(md, "image", text="")
621 col.label(text="UV Layer:")
622 col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="")
624 split = layout.split()
626 col.prop(md, "use_image_override")
627 col.prop(md, "projector_count", text="Projectors")
628 for proj in md.projectors:
629 col.prop(proj, "object", text="")
632 sub = col.column(align=True)
633 sub.prop(md, "aspect_x", text="Aspect X")
634 sub.prop(md, "aspect_y", text="Aspect Y")
636 sub = col.column(align=True)
637 sub.prop(md, "scale_x", text="Scale X")
638 sub.prop(md, "scale_y", text="Scale Y")
640 def WARP(self, layout, ob, md):
641 use_falloff = (md.falloff_type != 'NONE')
642 split = layout.split()
645 col.label(text="From:")
646 col.prop(md, "object_from", text="")
648 col.prop(md, "use_volume_preserve")
651 col.label(text="To:")
652 col.prop(md, "object_to", text="")
653 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
655 col = layout.column()
657 row = col.row(align=True)
658 row.prop(md, "strength")
660 row.prop(md, "falloff_radius")
662 col.prop(md, "falloff_type")
664 if md.falloff_type == 'CURVE':
665 col.template_curve_mapping(md, "falloff_curve")
668 split = layout.split()
670 col.label(text="Texture:")
671 col.template_ID(md, "texture", new="texture.new")
674 col.label(text="Texture Coordinates:")
675 col.prop(md, "texture_coords", text="")
677 if md.texture_coords == 'OBJECT':
678 layout.prop(md, "texture_coords_object", text="Object")
679 elif md.texture_coords == 'UV' and ob.type == 'MESH':
680 layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
682 def WAVE(self, layout, ob, md):
683 split = layout.split()
686 col.label(text="Motion:")
687 col.prop(md, "use_x")
688 col.prop(md, "use_y")
689 col.prop(md, "use_cyclic")
692 col.prop(md, "use_normal")
694 sub.active = md.use_normal
695 sub.prop(md, "use_normal_x", text="X")
696 sub.prop(md, "use_normal_y", text="Y")
697 sub.prop(md, "use_normal_z", text="Z")
699 split = layout.split()
702 col.label(text="Time:")
703 sub = col.column(align=True)
704 sub.prop(md, "time_offset", text="Offset")
705 sub.prop(md, "lifetime", text="Life")
706 col.prop(md, "damping_time", text="Damping")
709 col.label(text="Position:")
710 sub = col.column(align=True)
711 sub.prop(md, "start_position_x", text="X")
712 sub.prop(md, "start_position_y", text="Y")
713 col.prop(md, "falloff_radius", text="Falloff")
717 layout.prop(md, "start_position_object")
718 layout.prop_search(md, "vertex_group", ob, "vertex_groups")
719 split = layout.split(percentage=0.33)
721 col.label(text="Texture")
723 col.template_ID(md, "texture", new="texture.new")
724 layout.prop(md, "texture_coords")
725 if md.texture_coords == 'MAP_UV' and ob.type == 'MESH':
726 layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
727 elif md.texture_coords == 'OBJECT':
728 layout.prop(md, "texture_coords_object")
732 split = layout.split()
735 col.prop(md, "speed", slider=True)
736 col.prop(md, "height", slider=True)
739 col.prop(md, "width", slider=True)
740 col.prop(md, "narrowness", slider=True)
743 def vertex_weight_mask(layout, ob, md):
744 layout.label(text="Influence/Mask Options:")
746 split = layout.split(percentage=0.4)
747 split.label(text="Global Influence:")
748 split.prop(md, "mask_constant", text="")
750 if not md.mask_texture:
751 split = layout.split(percentage=0.4)
752 split.label(text="Vertex Group Mask:")
753 split.prop_search(md, "mask_vertex_group", ob, "vertex_groups", text="")
755 if not md.mask_vertex_group:
756 split = layout.split(percentage=0.4)
757 split.label(text="Texture Mask:")
758 split.template_ID(md, "mask_texture", new="texture.new")
760 split = layout.split()
763 col.label(text="Texture Coordinates:")
764 col.prop(md, "mask_tex_mapping", text="")
767 col.label(text="Use Channel:")
768 col.prop(md, "mask_tex_use_channel", text="")
770 if md.mask_tex_mapping == 'OBJECT':
771 layout.prop(md, "mask_tex_map_object", text="Object")
772 elif md.mask_tex_mapping == 'UV' and ob.type == 'MESH':
773 layout.prop_search(md, "mask_tex_uv_layer", ob.data, "uv_textures")
775 def VERTEX_WEIGHT_EDIT(self, layout, ob, md):
776 split = layout.split()
778 col.label(text="Vertex Group:")
779 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
782 col.label(text="Default Weight:")
783 col.prop(md, "default_weight", text="")
785 layout.prop(md, "falloff_type")
786 if md.falloff_type == 'CURVE':
787 col = layout.column()
788 col.template_curve_mapping(md, "map_curve")
790 split = layout.split(percentage=0.4)
791 split.prop(md, "use_add")
793 row.active = md.use_add
794 row.prop(md, "add_threshold")
796 split = layout.split(percentage=0.4)
797 split.prop(md, "use_remove")
799 row.active = md.use_remove
800 row.prop(md, "remove_threshold")
802 # Common mask options
804 self.vertex_weight_mask(layout, ob, md)
806 def VERTEX_WEIGHT_MIX(self, layout, ob, md):
807 split = layout.split()
810 col.label(text="Vertex Group A:")
811 col.prop_search(md, "vertex_group_a", ob, "vertex_groups", text="")
812 col.label(text="Default Weight A:")
813 col.prop(md, "default_weight_a", text="")
815 col.label(text="Mix Mode:")
816 col.prop(md, "mix_mode", text="")
819 col.label(text="Vertex Group B:")
820 col.prop_search(md, "vertex_group_b", ob, "vertex_groups", text="")
821 col.label(text="Default Weight B:")
822 col.prop(md, "default_weight_b", text="")
824 col.label(text="Mix Set:")
825 col.prop(md, "mix_set", text="")
827 # Common mask options
829 self.vertex_weight_mask(layout, ob, md)
831 def VERTEX_WEIGHT_PROXIMITY(self, layout, ob, md):
832 split = layout.split()
835 col.label(text="Vertex Group:")
836 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
839 col.label(text="Target Object:")
840 col.prop(md, "target", text="")
842 layout.row().prop(md, "proximity_mode", expand=True)
843 if md.proximity_mode == 'GEOMETRY':
844 layout.row().prop(md, "proximity_geometry", expand=True)
847 row.prop(md, "min_dist")
848 row.prop(md, "max_dist")
850 layout.prop(md, "falloff_type")
852 # Common mask options
854 self.vertex_weight_mask(layout, ob, md)
856 if __name__ == "__main__": # only for live edit.
857 bpy.utils.register_module(__name__)