Sculpt:
[blender.git] / release / scripts / ui / properties_physics_softbody.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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20 import bpy
21
22 narrowui = 180
23
24
25 from properties_physics_common import point_cache_ui
26 from properties_physics_common import effector_weights_ui
27
28
29 def softbody_panel_enabled(md):
30     return (md.point_cache.baked is False)
31
32
33 class PhysicButtonsPanel(bpy.types.Panel):
34     bl_space_type = 'PROPERTIES'
35     bl_region_type = 'WINDOW'
36     bl_context = "physics"
37
38     def poll(self, context):
39         ob = context.object
40         rd = context.scene.render_data
41         return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
42
43
44 class PHYSICS_PT_softbody(PhysicButtonsPanel):
45     bl_label = "Soft Body"
46
47     def draw(self, context):
48         layout = self.layout
49
50         md = context.soft_body
51         ob = context.object
52         wide_ui = context.region.width > narrowui
53
54         split = layout.split()
55         split.operator_context = 'EXEC_DEFAULT'
56
57         if md:
58             # remove modifier + settings
59             split.set_context_pointer("modifier", md)
60             split.operator("object.modifier_remove", text="Remove")
61
62             row = split.row(align=True)
63             row.prop(md, "render", text="")
64             row.prop(md, "realtime", text="")
65         else:
66             # add modifier
67             split.operator("object.modifier_add", text="Add").type = 'SOFT_BODY'
68             if wide_ui:
69                 split.column()
70
71         if md:
72             softbody = md.settings
73
74             # General
75             split = layout.split()
76             split.enabled = softbody_panel_enabled(md)
77
78             col = split.column()
79             col.label(text="Object:")
80             col.prop(softbody, "friction")
81             col.prop(softbody, "mass")
82             col.prop_object(softbody, "mass_vertex_group", ob, "vertex_groups", text="Mass:")
83
84             if wide_ui:
85                 col = split.column()
86             col.label(text="Simulation:")
87             col.prop(softbody, "speed")
88
89
90 class PHYSICS_PT_softbody_cache(PhysicButtonsPanel):
91     bl_label = "Soft Body Cache"
92     bl_default_closed = True
93
94     def poll(self, context):
95         return context.soft_body
96
97     def draw(self, context):
98         md = context.soft_body
99         point_cache_ui(self, context, md.point_cache, softbody_panel_enabled(md), 0, 0)
100
101
102 class PHYSICS_PT_softbody_goal(PhysicButtonsPanel):
103     bl_label = "Soft Body Goal"
104     bl_default_closed = True
105
106     def poll(self, context):
107         return context.soft_body
108
109     def draw_header(self, context):
110         softbody = context.soft_body.settings
111
112         self.layout.active = softbody_panel_enabled(context.soft_body)
113         self.layout.prop(softbody, "use_goal", text="")
114
115     def draw(self, context):
116         layout = self.layout
117
118         md = context.soft_body
119         softbody = md.settings
120         ob = context.object
121         wide_ui = context.region.width > narrowui
122
123         layout.active = softbody.use_goal and softbody_panel_enabled(md)
124
125         split = layout.split()
126
127         # Goal
128         split = layout.split()
129
130         col = split.column()
131         col.label(text="Goal Strengths:")
132         col.prop(softbody, "goal_default", text="Default")
133         sub = col.column(align=True)
134         sub.prop(softbody, "goal_min", text="Minimum")
135         sub.prop(softbody, "goal_max", text="Maximum")
136
137         if wide_ui:
138             col = split.column()
139         col.label(text="Goal Settings:")
140         col.prop(softbody, "goal_spring", text="Stiffness")
141         col.prop(softbody, "goal_friction", text="Damping")
142
143         layout.prop_object(softbody, "goal_vertex_group", ob, "vertex_groups", text="Vertex Group")
144
145
146 class PHYSICS_PT_softbody_edge(PhysicButtonsPanel):
147     bl_label = "Soft Body Edges"
148     bl_default_closed = True
149
150     def poll(self, context):
151         return context.soft_body
152
153     def draw_header(self, context):
154         softbody = context.soft_body.settings
155
156         self.layout.active = softbody_panel_enabled(context.soft_body)
157         self.layout.prop(softbody, "use_edges", text="")
158
159     def draw(self, context):
160         layout = self.layout
161
162         md = context.soft_body
163         softbody = md.settings
164         ob = context.object
165         wide_ui = context.region.width > narrowui
166
167         layout.active = softbody.use_edges and softbody_panel_enabled(md)
168
169         split = layout.split()
170
171         col = split.column()
172         col.label(text="Springs:")
173         col.prop(softbody, "pull")
174         col.prop(softbody, "push")
175         col.prop(softbody, "damp")
176         col.prop(softbody, "plastic")
177         col.prop(softbody, "bending")
178         col.prop(softbody, "spring_length", text="Length")
179         col.prop_object(softbody, "spring_vertex_group", ob, "vertex_groups", text="Springs:")
180         col.item_pointerR(softbody, "spring_vertex_group", ob, "vertex_groups", text="Springs:")
181
182         if wide_ui:
183             col = split.column()
184         col.prop(softbody, "stiff_quads")
185         sub = col.column()
186         sub.active = softbody.stiff_quads
187         sub.prop(softbody, "shear")
188
189         col.prop(softbody, "new_aero", text="Aero")
190         sub = col.column()
191         sub.enabled = softbody.new_aero
192         sub.prop(softbody, "aero", text="Factor")
193
194         col.label(text="Collision:")
195         col.prop(softbody, "edge_collision", text="Edge")
196         col.prop(softbody, "face_collision", text="Face")
197
198
199 class PHYSICS_PT_softbody_collision(PhysicButtonsPanel):
200     bl_label = "Soft Body Collision"
201     bl_default_closed = True
202
203     def poll(self, context):
204         return context.soft_body
205
206     def draw_header(self, context):
207         softbody = context.soft_body.settings
208
209         self.layout.active = softbody_panel_enabled(context.soft_body)
210         self.layout.prop(softbody, "self_collision", text="")
211
212     def draw(self, context):
213         layout = self.layout
214
215         md = context.soft_body
216         softbody = md.settings
217         wide_ui = context.region.width > narrowui
218
219         layout.active = softbody.self_collision and softbody_panel_enabled(md)
220
221         layout.label(text="Collision Type:")
222         if wide_ui:
223             layout.prop(softbody, "collision_type", expand=True)
224         else:
225             layout.prop(softbody, "collision_type", text="")
226
227         col = layout.column(align=True)
228         col.label(text="Ball:")
229         col.prop(softbody, "ball_size", text="Size")
230         col.prop(softbody, "ball_stiff", text="Stiffness")
231         col.prop(softbody, "ball_damp", text="Dampening")
232
233
234 class PHYSICS_PT_softbody_solver(PhysicButtonsPanel):
235     bl_label = "Soft Body Solver"
236     bl_default_closed = True
237
238     def poll(self, context):
239         return context.soft_body
240
241     def draw(self, context):
242         layout = self.layout
243
244         md = context.soft_body
245         softbody = md.settings
246         wide_ui = context.region.width > narrowui
247
248         layout.active = softbody_panel_enabled(md)
249
250         # Solver
251         split = layout.split()
252
253         col = split.column(align=True)
254         col.label(text="Step Size:")
255         col.prop(softbody, "minstep")
256         col.prop(softbody, "maxstep")
257         col.prop(softbody, "auto_step", text="Auto-Step")
258
259         if wide_ui:
260             col = split.column()
261         col.prop(softbody, "error_limit")
262         col.label(text="Helpers:")
263         col.prop(softbody, "choke")
264         col.prop(softbody, "fuzzy")
265
266         layout.label(text="Diagnostics:")
267         layout.prop(softbody, "diagnose")
268
269
270 class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel):
271     bl_label = "Soft Body Field Weights"
272     bl_default_closed = True
273
274     def poll(self, context):
275         return (context.soft_body)
276
277     def draw(self, context):
278         md = context.soft_body
279         softbody = md.settings
280
281         effector_weights_ui(self, context, softbody.effector_weights)
282
283 bpy.types.register(PHYSICS_PT_softbody)
284 bpy.types.register(PHYSICS_PT_softbody_cache)
285 bpy.types.register(PHYSICS_PT_softbody_goal)
286 bpy.types.register(PHYSICS_PT_softbody_edge)
287 bpy.types.register(PHYSICS_PT_softbody_collision)
288 bpy.types.register(PHYSICS_PT_softbody_solver)
289 bpy.types.register(PHYSICS_PT_softbody_field_weights)