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 EDGE_SPLIT(self, layout, ob, md):
234 split = layout.split()
237 col.prop(md, "use_edge_angle", text="Edge Angle")
239 sub.active = md.use_edge_angle
240 sub.prop(md, "split_angle")
242 split.prop(md, "use_edge_sharp", text="Sharp Edges")
244 def EXPLODE(self, layout, ob, md):
245 split = layout.split()
248 col.label(text="Vertex group:")
249 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
251 sub.active = bool(md.vertex_group)
252 sub.prop(md, "protect")
253 col.label(text="Particle UV")
254 col.prop_search(md, "particle_uv", ob.data, "uv_textures", text="")
257 col.prop(md, "use_edge_cut")
258 col.prop(md, "show_unborn")
259 col.prop(md, "show_alive")
260 col.prop(md, "show_dead")
261 col.prop(md, "use_size")
263 layout.operator("object.explode_refresh", text="Refresh")
265 def FLUID_SIMULATION(self, layout, ob, md):
266 layout.label(text="Settings can be found inside the Physics context")
268 def HOOK(self, layout, ob, md):
269 split = layout.split()
272 col.label(text="Object:")
273 col.prop(md, "object", text="")
274 if md.object and md.object.type == 'ARMATURE':
275 col.label(text="Bone:")
276 col.prop_search(md, "subtarget", md.object.data, "bones", text="")
278 col.label(text="Vertex Group:")
279 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
283 split = layout.split()
286 col.prop(md, "falloff")
287 col.prop(md, "force", slider=True)
290 col.operator("object.hook_reset", text="Reset")
291 col.operator("object.hook_recenter", text="Recenter")
293 if ob.mode == 'EDIT':
296 row.operator("object.hook_select", text="Select")
297 row.operator("object.hook_assign", text="Assign")
299 def LATTICE(self, layout, ob, md):
300 split = layout.split()
303 col.label(text="Object:")
304 col.prop(md, "object", text="")
307 col.label(text="Vertex Group:")
308 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
310 def MASK(self, layout, ob, md):
311 split = layout.split()
314 col.label(text="Mode:")
315 col.prop(md, "mode", text="")
317 if md.mode == 'ARMATURE':
318 col.label(text="Armature:")
319 col.prop(md, "armature", text="")
320 elif md.mode == 'VERTEX_GROUP':
321 col.label(text="Vertex Group:")
322 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
325 sub.active = bool(md.vertex_group)
326 sub.prop(md, "invert_vertex_group")
328 def MESH_DEFORM(self, layout, ob, md):
329 split = layout.split()
333 sub.label(text="Object:")
334 sub.prop(md, "object", text="")
335 sub.active = not md.is_bound
337 col.label(text="Vertex Group:")
338 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
341 sub.active = bool(md.vertex_group)
342 sub.prop(md, "invert_vertex_group")
347 layout.operator("object.meshdeform_bind", text="Unbind")
349 layout.operator("object.meshdeform_bind", text="Bind")
352 row.prop(md, "precision")
353 row.prop(md, "use_dynamic_bind")
355 def MIRROR(self, layout, ob, md):
356 split = layout.split(percentage=0.25)
359 col.label(text="Axis:")
360 col.prop(md, "use_x")
361 col.prop(md, "use_y")
362 col.prop(md, "use_z")
365 col.label(text="Options:")
366 col.prop(md, "use_mirror_merge", text="Merge")
367 col.prop(md, "use_clip", text="Clipping")
368 col.prop(md, "use_mirror_vertex_groups", text="Vertex Groups")
371 col.label(text="Textures:")
372 col.prop(md, "use_mirror_u", text="U")
373 col.prop(md, "use_mirror_v", text="V")
375 col = layout.column()
377 if md.use_mirror_merge == True:
378 col.prop(md, "merge_threshold")
379 col.label(text="Mirror Object:")
380 col.prop(md, "mirror_object", text="")
382 def MULTIRES(self, layout, ob, md):
383 layout.row().prop(md, "subdivision_type", expand=True)
385 split = layout.split()
387 col.prop(md, "levels", text="Preview")
388 col.prop(md, "sculpt_levels", text="Sculpt")
389 col.prop(md, "render_levels", text="Render")
393 col.enabled = ob.mode != 'EDIT'
394 col.operator("object.multires_subdivide", text="Subdivide")
395 col.operator("object.multires_higher_levels_delete", text="Delete Higher")
396 col.operator("object.multires_reshape", text="Reshape")
397 col.operator("object.multires_base_apply", text="Apply Base")
398 col.prop(md, "use_subsurf_uv")
399 col.prop(md, "show_only_control_edges")
403 col = layout.column()
406 row.operator("object.multires_external_pack", text="Pack External")
409 row.prop(md, "filepath", text="")
411 row.operator("object.multires_external_save", text="Save External...")
414 def PARTICLE_INSTANCE(self, layout, ob, md):
415 layout.prop(md, "object")
416 layout.prop(md, "particle_system_index", text="Particle System")
418 split = layout.split()
420 col.label(text="Create From:")
421 col.prop(md, "use_normal")
422 col.prop(md, "use_children")
423 col.prop(md, "use_size")
426 col.label(text="Show Particles When:")
427 col.prop(md, "show_alive")
428 col.prop(md, "show_unborn")
429 col.prop(md, "show_dead")
433 layout.prop(md, "use_path", text="Create Along Paths")
435 split = layout.split()
436 split.active = md.use_path
438 col.row().prop(md, "axis", expand=True)
439 col.prop(md, "use_preserve_shape")
442 col.prop(md, "position", slider=True)
443 col.prop(md, "random_position", text="Random", slider=True)
445 def PARTICLE_SYSTEM(self, layout, ob, md):
446 layout.label(text="Settings can be found inside the Particle context")
448 def SCREW(self, layout, ob, md):
449 split = layout.split()
453 col.prop(md, "object", text="AxisOb")
454 col.prop(md, "angle")
455 col.prop(md, "steps")
456 col.prop(md, "render_steps")
460 row.active = (md.object is None or md.use_object_screw_offset == False)
461 row.prop(md, "screw_offset")
463 row.active = (md.object is not None)
464 row.prop(md, "use_object_screw_offset")
465 col.prop(md, "use_normal_calculate")
466 col.prop(md, "use_normal_flip")
467 col.prop(md, "iterations")
469 def SHRINKWRAP(self, layout, ob, md):
470 split = layout.split()
472 col.label(text="Target:")
473 col.prop(md, "target", text="")
475 col.label(text="Vertex Group:")
476 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
478 split = layout.split()
481 col.prop(md, "offset")
482 col.prop(md, "subsurf_levels")
485 col.label(text="Mode:")
486 col.prop(md, "wrap_method", text="")
488 if md.wrap_method == 'PROJECT':
489 split = layout.split(percentage=0.25)
492 col.label(text="Axis:")
493 col.prop(md, "use_project_x")
494 col.prop(md, "use_project_y")
495 col.prop(md, "use_project_z")
498 col.label(text="Direction:")
499 col.prop(md, "use_negative_direction")
500 col.prop(md, "use_positive_direction")
503 col.label(text="Cull Faces:")
504 col.prop(md, "cull_face", expand=True)
506 layout.label(text="Auxiliary Target:")
507 layout.prop(md, "auxiliary_target", text="")
509 elif md.wrap_method == 'NEAREST_SURFACEPOINT':
510 layout.prop(md, "use_keep_above_surface")
512 def SIMPLE_DEFORM(self, layout, ob, md):
513 split = layout.split()
516 col.label(text="Mode:")
517 col.prop(md, "deform_method", text="")
520 col.label(text="Vertex Group:")
521 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
523 split = layout.split()
526 col.label(text="Origin:")
527 col.prop(md, "origin", text="")
529 sub.active = (md.origin is not None)
530 sub.prop(md, "use_relative")
533 col.label(text="Deform:")
534 col.prop(md, "factor")
535 col.prop(md, "limits", slider=True)
536 if md.deform_method in {'TAPER', 'STRETCH'}:
537 col.prop(md, "lock_x")
538 col.prop(md, "lock_y")
540 def SMOKE(self, layout, ob, md):
541 layout.label(text="Settings can be found inside the Physics context")
543 def SMOOTH(self, layout, ob, md):
544 split = layout.split(percentage=0.25)
547 col.label(text="Axis:")
548 col.prop(md, "use_x")
549 col.prop(md, "use_y")
550 col.prop(md, "use_z")
553 col.prop(md, "factor")
554 col.prop(md, "iterations")
555 col.label(text="Vertex Group:")
556 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
558 def SOFT_BODY(self, layout, ob, md):
559 layout.label(text="Settings can be found inside the Physics context")
561 def SOLIDIFY(self, layout, ob, md):
562 split = layout.split()
565 col.prop(md, "thickness")
566 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
568 col.label(text="Crease:")
569 col.prop(md, "edge_crease_inner", text="Inner")
570 col.prop(md, "edge_crease_outer", text="Outer")
571 col.prop(md, "edge_crease_rim", text="Rim")
572 col.label(text="Material Index Offset:")
576 col.prop(md, "offset")
578 sub.active = bool(md.vertex_group)
579 sub.prop(md, "invert_vertex_group", text="Invert")
580 sub.prop(md, "thickness_vertex_group", text="Factor")
582 col.prop(md, "use_even_offset")
583 col.prop(md, "use_quality_normals")
584 col.prop(md, "use_rim")
587 row = sub.split(align=True, percentage=0.4)
588 row.prop(md, "material_offset", text="")
590 row.active = md.use_rim
591 row.prop(md, "material_offset_rim", text="Rim")
593 def SUBSURF(self, layout, ob, md):
594 layout.row().prop(md, "subdivision_type", expand=True)
596 split = layout.split()
598 col.label(text="Subdivisions:")
599 col.prop(md, "levels", text="View")
600 col.prop(md, "render_levels", text="Render")
603 col.label(text="Options:")
604 col.prop(md, "use_subsurf_uv")
605 col.prop(md, "show_only_control_edges")
607 def SURFACE(self, layout, ob, md):
608 layout.label(text="Settings can be found inside the Physics context")
610 def UV_PROJECT(self, layout, ob, md):
611 split = layout.split()
614 col.label(text="Image:")
615 col.prop(md, "image", text="")
618 col.label(text="UV Layer:")
619 col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="")
621 split = layout.split()
623 col.prop(md, "use_image_override")
624 col.prop(md, "projector_count", text="Projectors")
625 for proj in md.projectors:
626 col.prop(proj, "object", text="")
629 sub = col.column(align=True)
630 sub.prop(md, "aspect_x", text="Aspect X")
631 sub.prop(md, "aspect_y", text="Aspect Y")
633 sub = col.column(align=True)
634 sub.prop(md, "scale_x", text="Scale X")
635 sub.prop(md, "scale_y", text="Scale Y")
637 def WARP(self, layout, ob, md):
638 use_falloff = (md.falloff_type != 'NONE')
639 split = layout.split()
642 col.label(text="From:")
643 col.prop(md, "object_from", text="")
645 col.prop(md, "use_volume_preserve")
648 col.label(text="To:")
649 col.prop(md, "object_to", text="")
650 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
652 col = layout.column()
654 row = col.row(align=True)
655 row.prop(md, "strength")
657 row.prop(md, "falloff_radius")
659 col.prop(md, "falloff_type")
661 if md.falloff_type == 'CURVE':
662 col.template_curve_mapping(md, "falloff_curve")
665 split = layout.split()
667 col.label(text="Texture:")
668 col.template_ID(md, "texture", new="texture.new")
671 col.label(text="Texture Coordinates:")
672 col.prop(md, "texture_coords", text="")
674 if md.texture_coords == 'OBJECT':
675 layout.prop(md, "texture_coords_object", text="Object")
676 elif md.texture_coords == 'UV' and ob.type == 'MESH':
677 layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
679 def WAVE(self, layout, ob, md):
680 split = layout.split()
683 col.label(text="Motion:")
684 col.prop(md, "use_x")
685 col.prop(md, "use_y")
686 col.prop(md, "use_cyclic")
689 col.prop(md, "use_normal")
691 sub.active = md.use_normal
692 sub.prop(md, "use_normal_x", text="X")
693 sub.prop(md, "use_normal_y", text="Y")
694 sub.prop(md, "use_normal_z", text="Z")
696 split = layout.split()
699 col.label(text="Time:")
700 sub = col.column(align=True)
701 sub.prop(md, "time_offset", text="Offset")
702 sub.prop(md, "lifetime", text="Life")
703 col.prop(md, "damping_time", text="Damping")
706 col.label(text="Position:")
707 sub = col.column(align=True)
708 sub.prop(md, "start_position_x", text="X")
709 sub.prop(md, "start_position_y", text="Y")
710 col.prop(md, "falloff_radius", text="Falloff")
714 layout.prop(md, "start_position_object")
715 layout.prop_search(md, "vertex_group", ob, "vertex_groups")
716 split = layout.split(percentage=0.33)
718 col.label(text="Texture")
720 col.template_ID(md, "texture", new="texture.new")
721 layout.prop(md, "texture_coords")
722 if md.texture_coords == 'MAP_UV' and ob.type == 'MESH':
723 layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
724 elif md.texture_coords == 'OBJECT':
725 layout.prop(md, "texture_coords_object")
729 split = layout.split()
732 col.prop(md, "speed", slider=True)
733 col.prop(md, "height", slider=True)
736 col.prop(md, "width", slider=True)
737 col.prop(md, "narrowness", slider=True)
740 def vertex_weight_mask(layout, ob, md):
741 layout.label(text="Influence/Mask Options:")
743 split = layout.split(percentage=0.4)
744 split.label(text="Global Influence:")
745 split.prop(md, "mask_constant", text="")
747 if not md.mask_texture:
748 split = layout.split(percentage=0.4)
749 split.label(text="Vertex Group Mask:")
750 split.prop_search(md, "mask_vertex_group", ob, "vertex_groups", text="")
752 if not md.mask_vertex_group:
753 split = layout.split(percentage=0.4)
754 split.label(text="Texture Mask:")
755 split.template_ID(md, "mask_texture", new="texture.new")
757 split = layout.split()
760 col.label(text="Texture Coordinates:")
761 col.prop(md, "mask_tex_mapping", text="")
764 col.label(text="Use Channel:")
765 col.prop(md, "mask_tex_use_channel", text="")
767 if md.mask_tex_mapping == 'OBJECT':
768 layout.prop(md, "mask_tex_map_object", text="Object")
769 elif md.mask_tex_mapping == 'UV' and ob.type == 'MESH':
770 layout.prop_search(md, "mask_tex_uv_layer", ob.data, "uv_textures")
772 def VERTEX_WEIGHT_EDIT(self, layout, ob, md):
773 split = layout.split()
775 col.label(text="Vertex Group:")
776 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
779 col.label(text="Default Weight:")
780 col.prop(md, "default_weight", text="")
782 layout.prop(md, "falloff_type")
783 if md.falloff_type == 'CURVE':
784 col = layout.column()
785 col.template_curve_mapping(md, "map_curve")
787 split = layout.split(percentage=0.4)
788 split.prop(md, "use_add")
790 row.active = md.use_add
791 row.prop(md, "add_threshold")
793 split = layout.split(percentage=0.4)
794 split.prop(md, "use_remove")
796 row.active = md.use_remove
797 row.prop(md, "remove_threshold")
799 # Common mask options
801 self.vertex_weight_mask(layout, ob, md)
803 def VERTEX_WEIGHT_MIX(self, layout, ob, md):
804 split = layout.split()
807 col.label(text="Vertex Group A:")
808 col.prop_search(md, "vertex_group_a", ob, "vertex_groups", text="")
809 col.label(text="Default Weight A:")
810 col.prop(md, "default_weight_a", text="")
812 col.label(text="Mix Mode:")
813 col.prop(md, "mix_mode", text="")
816 col.label(text="Vertex Group B:")
817 col.prop_search(md, "vertex_group_b", ob, "vertex_groups", text="")
818 col.label(text="Default Weight B:")
819 col.prop(md, "default_weight_b", text="")
821 col.label(text="Mix Set:")
822 col.prop(md, "mix_set", text="")
824 # Common mask options
826 self.vertex_weight_mask(layout, ob, md)
828 def VERTEX_WEIGHT_PROXIMITY(self, layout, ob, md):
829 split = layout.split()
832 col.label(text="Vertex Group:")
833 col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
836 col.label(text="Target Object:")
837 col.prop(md, "target", text="")
839 layout.row().prop(md, "proximity_mode", expand=True)
840 if md.proximity_mode == 'GEOMETRY':
841 layout.row().prop(md, "proximity_geometry", expand=True)
844 row.prop(md, "min_dist")
845 row.prop(md, "max_dist")
847 layout.prop(md, "falloff_type")
849 # Common mask options
851 self.vertex_weight_mask(layout, ob, md)
853 if __name__ == "__main__": # only for live edit.
854 bpy.utils.register_module(__name__)