Workspace: Move engines to workspace and Properties Editor cleanup
[blender.git] / release / scripts / startup / bl_ui / properties_physics_cloth.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 Menu, Panel
22
23 from bl_ui.properties_physics_common import (
24         point_cache_ui,
25         effector_weights_ui,
26         )
27
28
29 def cloth_panel_enabled(md):
30     return md.point_cache.is_baked is False
31
32
33 class CLOTH_MT_presets(Menu):
34     bl_label = "Cloth Presets"
35     preset_subdir = "cloth"
36     preset_operator = "script.execute_preset"
37     draw = Menu.draw_preset
38
39
40 class PhysicButtonsPanel:
41     bl_space_type = 'PROPERTIES'
42     bl_region_type = 'WINDOW'
43     bl_context = "physics"
44
45     @classmethod
46     def poll(cls, context):
47         ob = context.object
48         view_render = context.scene.view_render
49         return (ob and ob.type == 'MESH') and (view_render.engine in cls.COMPAT_ENGINES) and (context.cloth)
50
51
52 class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel):
53     bl_label = "Cloth"
54     COMPAT_ENGINES = {'BLENDER_RENDER'}
55
56     def draw(self, context):
57         layout = self.layout
58
59         md = context.cloth
60         ob = context.object
61         cloth = md.settings
62
63         layout.active = cloth_panel_enabled(md)
64
65         split = layout.split(percentage=0.25)
66
67         col = split.column()
68
69         split.label(text="Presets:")
70         sub = split.row(align=True)
71         sub.menu("CLOTH_MT_presets", text=bpy.types.CLOTH_MT_presets.bl_label)
72         sub.operator("cloth.preset_add", text="", icon='ZOOMIN')
73         sub.operator("cloth.preset_add", text="", icon='ZOOMOUT').remove_active = True
74
75         split = layout.split(percentage=0.25)
76
77         split.label(text="Quality:")
78         split.prop(cloth, "quality", text="Steps")
79
80         split = layout.split(percentage=0.25)
81
82         split.label(text="Speed:")
83         split.prop(cloth, "time_scale", text="Multiplier")
84
85         split = layout.split()
86
87         col = split.column()
88
89         col.label(text="Material:")
90         col.prop(cloth, "mass")
91         col.prop(cloth, "structural_stiffness", text="Structural")
92         col.prop(cloth, "bending_stiffness", text="Bending")
93
94         col = split.column()
95
96         col.label(text="Damping:")
97         col.prop(cloth, "spring_damping", text="Spring")
98         col.prop(cloth, "air_damping", text="Air")
99         col.prop(cloth, "vel_damping", text="Velocity")
100
101         split = layout.split()
102
103         col = split.column()
104
105         col.prop(cloth, "use_pin_cloth", text="Pinning:")
106         sub = col.column()
107         sub.active = cloth.use_pin_cloth
108         sub.prop_search(cloth, "vertex_group_mass", ob, "vertex_groups", text="")
109         sub.prop(cloth, "pin_stiffness", text="Stiffness")
110
111         # Disabled for now
112         """
113         if cloth.vertex_group_mass:
114             layout.label(text="Goal:")
115
116             col = layout.column_flow()
117             col.prop(cloth, "goal_default", text="Default")
118             col.prop(cloth, "goal_spring", text="Stiffness")
119             col.prop(cloth, "goal_friction", text="Friction")
120         """
121
122         col = split.column()
123
124         col.prop(cloth, "use_dynamic_mesh", text="Dynamic Mesh")
125
126         key = ob.data.shape_keys
127
128         if key:
129             sub = col.column()
130             sub.active = not cloth.use_dynamic_mesh
131             sub.label(text="Rest Shape Key:")
132             sub.prop_search(cloth, "rest_shape_key", key, "key_blocks", text="")
133
134
135 class PHYSICS_PT_cloth_cache(PhysicButtonsPanel, Panel):
136     bl_label = "Cloth Cache"
137     bl_options = {'DEFAULT_CLOSED'}
138     COMPAT_ENGINES = {'BLENDER_RENDER'}
139
140     def draw(self, context):
141         md = context.cloth
142         point_cache_ui(self, context, md.point_cache, cloth_panel_enabled(md), 'CLOTH')
143
144
145 class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel):
146     bl_label = "Cloth Collision"
147     bl_options = {'DEFAULT_CLOSED'}
148     COMPAT_ENGINES = {'BLENDER_RENDER'}
149
150     def draw_header(self, context):
151         cloth = context.cloth.collision_settings
152
153         self.layout.active = cloth_panel_enabled(context.cloth)
154         self.layout.prop(cloth, "use_collision", text="")
155
156     def draw(self, context):
157         layout = self.layout
158
159         cloth = context.cloth.collision_settings
160         md = context.cloth
161         ob = context.object
162
163         layout.active = cloth.use_collision and cloth_panel_enabled(md)
164
165         split = layout.split()
166
167         col = split.column()
168         col.prop(cloth, "collision_quality", text="Quality")
169         col.prop(cloth, "distance_min", slider=True, text="Distance")
170         col.prop(cloth, "repel_force", slider=True, text="Repel")
171         col.prop(cloth, "distance_repel", slider=True, text="Repel Distance")
172         col.prop(cloth, "friction")
173
174         col = split.column()
175         col.prop(cloth, "use_self_collision", text="Self Collision")
176         sub = col.column()
177         sub.active = cloth.use_self_collision
178         sub.prop(cloth, "self_collision_quality", text="Quality")
179         sub.prop(cloth, "self_distance_min", slider=True, text="Distance")
180         sub.prop_search(cloth, "vertex_group_self_collisions", ob, "vertex_groups", text="")
181
182         layout.prop(cloth, "group")
183
184
185 class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel):
186     bl_label = "Cloth Stiffness Scaling"
187     bl_options = {'DEFAULT_CLOSED'}
188     COMPAT_ENGINES = {'BLENDER_RENDER'}
189
190     def draw_header(self, context):
191         cloth = context.cloth.settings
192
193         self.layout.active = cloth_panel_enabled(context.cloth)
194         self.layout.prop(cloth, "use_stiffness_scale", text="")
195
196     def draw(self, context):
197         layout = self.layout
198
199         md = context.cloth
200         ob = context.object
201         cloth = context.cloth.settings
202
203         layout.active = (cloth.use_stiffness_scale and cloth_panel_enabled(md))
204
205         split = layout.split()
206
207         col = split.column()
208         col.label(text="Structural Stiffness:")
209         col.prop_search(cloth, "vertex_group_structural_stiffness", ob, "vertex_groups", text="")
210         col.prop(cloth, "structural_stiffness_max", text="Max")
211
212         col = split.column()
213         col.label(text="Bending Stiffness:")
214         col.prop_search(cloth, "vertex_group_bending", ob, "vertex_groups", text="")
215         col.prop(cloth, "bending_stiffness_max", text="Max")
216
217
218 class PHYSICS_PT_cloth_sewing(PhysicButtonsPanel, Panel):
219     bl_label = "Cloth Sewing Springs"
220     bl_options = {'DEFAULT_CLOSED'}
221     COMPAT_ENGINES = {'BLENDER_RENDER'}
222
223     def draw_header(self, context):
224         cloth = context.cloth.settings
225
226         self.layout.active = cloth_panel_enabled(context.cloth)
227         self.layout.prop(cloth, "use_sewing_springs", text="")
228
229     def draw(self, context):
230         layout = self.layout
231
232         md = context.cloth
233         ob = context.object
234         cloth = context.cloth.settings
235
236         layout.active = (cloth.use_sewing_springs and cloth_panel_enabled(md))
237
238         layout.prop(cloth, "sewing_force_max", text="Sewing Force")
239
240         split = layout.split()
241
242         col = split.column(align=True)
243         col.label(text="Shrinking:")
244         col.prop_search(cloth, "vertex_group_shrink", ob, "vertex_groups", text="")
245
246         col = split.column(align=True)
247         col.label()
248         col.prop(cloth, "shrink_min", text="Min")
249         col.prop(cloth, "shrink_max", text="Max")
250
251
252 class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel, Panel):
253     bl_label = "Cloth Field Weights"
254     bl_options = {'DEFAULT_CLOSED'}
255     COMPAT_ENGINES = {'BLENDER_RENDER'}
256
257     def draw(self, context):
258         cloth = context.cloth.settings
259         effector_weights_ui(self, context, cloth.effector_weights, 'CLOTH')
260
261 classes = (
262     CLOTH_MT_presets,
263     PHYSICS_PT_cloth,
264     PHYSICS_PT_cloth_cache,
265     PHYSICS_PT_cloth_collision,
266     PHYSICS_PT_cloth_stiffness,
267     PHYSICS_PT_cloth_sewing,
268     PHYSICS_PT_cloth_field_weights,
269 )
270
271 if __name__ == "__main__":  # only for live edit.
272     from bpy.utils import register_class
273     for cls in classes:
274         register_class(cls)