Merge with trunk, revision 28528 - 28976.
[blender-staging.git] / release / scripts / ui / properties_physics_fluid.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
22 narrowui = bpy.context.user_preferences.view.properties_width_check
23
24
25 class PhysicButtonsPanel(bpy.types.Panel):
26     bl_space_type = 'PROPERTIES'
27     bl_region_type = 'WINDOW'
28     bl_context = "physics"
29
30     def poll(self, context):
31         ob = context.object
32         rd = context.scene.render
33         return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
34
35
36 class PHYSICS_PT_fluid(PhysicButtonsPanel):
37     bl_label = "Fluid"
38
39     def draw(self, context):
40         layout = self.layout
41
42         md = context.fluid
43         wide_ui = context.region.width > narrowui
44
45         split = layout.split()
46
47         if md:
48             # remove modifier + settings
49             split.set_context_pointer("modifier", md)
50             split.operator("object.modifier_remove", text="Remove")
51
52             row = split.row(align=True)
53             row.prop(md, "render", text="")
54             row.prop(md, "realtime", text="")
55
56             fluid = md.settings
57
58         else:
59             # add modifier
60             split.operator("object.modifier_add", text="Add").type = 'FLUID_SIMULATION'
61             if wide_ui:
62                 split.label()
63
64             fluid = None
65
66
67         if fluid:
68             if wide_ui:
69                 row = layout.row()
70                 row.prop(fluid, "type")
71                 if fluid.type not in ('NONE', 'DOMAIN', 'PARTICLE'):
72                     row.prop(fluid, "active", text="")
73             else:
74                 layout.prop(fluid, "type", text="")
75                 if fluid.type not in ('NONE', 'DOMAIN', 'PARTICLE'):
76                     layout.prop(fluid, "active", text="")
77
78             layout = layout.column()
79             if fluid.type not in ('NONE', 'DOMAIN', 'PARTICLE'):
80                 layout.active = fluid.active
81
82             if fluid.type == 'DOMAIN':
83                 layout.operator("fluid.bake", text="Bake Fluid Simulation", icon='MOD_FLUIDSIM')
84                 split = layout.split()
85
86                 col = split.column()
87                 col.label(text="Resolution:")
88                 col.prop(fluid, "resolution", text="Final")
89                 col.label(text="Render Display:")
90                 col.prop(fluid, "render_display_mode", text="")
91
92                 if wide_ui:
93                     col = split.column()
94                 col.label(text="Required Memory: " + fluid.memory_estimate)
95                 col.prop(fluid, "preview_resolution", text="Preview")
96                 col.label(text="Viewport Display:")
97                 col.prop(fluid, "viewport_display_mode", text="")
98
99                 split = layout.split()
100
101                 col = split.column()
102                 col.label(text="Time:")
103                 sub = col.column(align=True)
104                 sub.prop(fluid, "start_time", text="Start")
105                 sub.prop(fluid, "end_time", text="End")
106
107                 if wide_ui:
108                     col = split.column()
109                     col.label()
110                 col.prop(fluid, "generate_speed_vectors")
111                 col.prop(fluid, "reverse_frames")
112
113                 layout.prop(fluid, "path", text="")
114
115             elif fluid.type == 'FLUID':
116                 split = layout.split()
117
118                 col = split.column()
119                 col.label(text="Volume Initialization:")
120                 col.prop(fluid, "volume_initialization", text="")
121                 col.prop(fluid, "export_animated_mesh")
122
123                 if wide_ui:
124                     col = split.column()
125                 col.label(text="Initial Velocity:")
126                 col.prop(fluid, "initial_velocity", text="")
127
128             elif fluid.type == 'OBSTACLE':
129                 split = layout.split()
130
131                 col = split.column()
132                 col.label(text="Volume Initialization:")
133                 col.prop(fluid, "volume_initialization", text="")
134                 col.prop(fluid, "export_animated_mesh")
135
136                 if wide_ui:
137                     col = split.column()
138                 col.label(text="Slip Type:")
139                 col.prop(fluid, "slip_type", text="")
140                 if fluid.slip_type == 'PARTIALSLIP':
141                     col.prop(fluid, "partial_slip_factor", slider=True, text="Amount")
142
143                 col.label(text="Impact:")
144                 col.prop(fluid, "impact_factor", text="Factor")
145
146             elif fluid.type == 'INFLOW':
147                 split = layout.split()
148
149                 col = split.column()
150                 col.label(text="Volume Initialization:")
151                 col.prop(fluid, "volume_initialization", text="")
152                 col.prop(fluid, "export_animated_mesh")
153                 col.prop(fluid, "local_coordinates")
154
155                 if wide_ui:
156                     col = split.column()
157                 col.label(text="Inflow Velocity:")
158                 col.prop(fluid, "inflow_velocity", text="")
159
160             elif fluid.type == 'OUTFLOW':
161                 split = layout.split()
162
163                 col = split.column()
164                 col.label(text="Volume Initialization:")
165                 col.prop(fluid, "volume_initialization", text="")
166                 col.prop(fluid, "export_animated_mesh")
167
168                 if wide_ui:
169                     split.column()
170
171             elif fluid.type == 'PARTICLE':
172                 split = layout.split()
173
174                 col = split.column()
175                 col.label(text="Influence:")
176                 col.prop(fluid, "particle_influence", text="Size")
177                 col.prop(fluid, "alpha_influence", text="Alpha")
178
179                 if wide_ui:
180                     col = split.column()
181                 col.label(text="Type:")
182                 col.prop(fluid, "drops")
183                 col.prop(fluid, "floats")
184                 col.prop(fluid, "tracer")
185
186                 layout.prop(fluid, "path", text="")
187
188             elif fluid.type == 'CONTROL':
189                 split = layout.split()
190
191                 col = split.column()
192                 col.label(text="")
193                 col.prop(fluid, "quality", slider=True)
194                 col.prop(fluid, "reverse_frames")
195
196                 if wide_ui:
197                     col = split.column()
198                 col.label(text="Time:")
199                 sub = col.column(align=True)
200                 sub.prop(fluid, "start_time", text="Start")
201                 sub.prop(fluid, "end_time", text="End")
202
203                 split = layout.split()
204
205                 col = split.column()
206                 col.label(text="Attraction Force:")
207                 sub = col.column(align=True)
208                 sub.prop(fluid, "attraction_strength", text="Strength")
209                 sub.prop(fluid, "attraction_radius", text="Radius")
210
211                 if wide_ui:
212                     col = split.column()
213                 col.label(text="Velocity Force:")
214                 sub = col.column(align=True)
215                 sub.prop(fluid, "velocity_strength", text="Strength")
216                 sub.prop(fluid, "velocity_radius", text="Radius")
217
218
219 class PHYSICS_PT_domain_gravity(PhysicButtonsPanel):
220     bl_label = "Domain World"
221     bl_default_closed = True
222
223     def poll(self, context):
224         md = context.fluid
225         return md and (md.settings.type == 'DOMAIN')
226
227     def draw(self, context):
228         layout = self.layout
229
230         fluid = context.fluid.settings
231         scene = context.scene
232         wide_ui = context.region.width > narrowui
233
234         split = layout.split()
235
236         col = split.column()
237         if scene.use_gravity:
238             col.label(text="Using Scene Gravity", icon="SCENE_DATA")
239             sub = col.column()
240             sub.enabled = False
241             sub.prop(fluid, "gravity", text="")
242         else:
243             col.label(text="Gravity:")
244             col.prop(fluid, "gravity", text="")
245
246         if scene.unit_settings.system != 'NONE':
247             col.label(text="Using Scene Size Units", icon="SCENE_DATA")
248             sub = col.column()
249             sub.enabled = False
250             sub.prop(fluid, "real_world_size", text="Metres")
251         else:
252             col.label(text="Real World Size:")
253             col.prop(fluid, "real_world_size", text="Metres")
254
255         if wide_ui:
256             col = split.column()
257         col.label(text="Viscosity Presets:")
258         sub = col.column(align=True)
259         sub.prop(fluid, "viscosity_preset", text="")
260
261         if fluid.viscosity_preset == 'MANUAL':
262             sub.prop(fluid, "viscosity_base", text="Base")
263             sub.prop(fluid, "viscosity_exponent", text="Exponent", slider=True)
264
265         col.label(text="Optimization:")
266         col.prop(fluid, "grid_levels", slider=True)
267         col.prop(fluid, "compressibility", slider=True)
268
269
270 class PHYSICS_PT_domain_boundary(PhysicButtonsPanel):
271     bl_label = "Domain Boundary"
272     bl_default_closed = True
273
274     def poll(self, context):
275         md = context.fluid
276         return md and (md.settings.type == 'DOMAIN')
277
278     def draw(self, context):
279         layout = self.layout
280
281         fluid = context.fluid.settings
282         wide_ui = context.region.width > narrowui
283
284         split = layout.split()
285
286         col = split.column()
287         col.label(text="Slip Type:")
288         col.prop(fluid, "slip_type", text="")
289         if fluid.slip_type == 'PARTIALSLIP':
290             col.prop(fluid, "partial_slip_factor", slider=True, text="Amount")
291
292         if wide_ui:
293             col = split.column()
294         col.label(text="Surface:")
295         col.prop(fluid, "surface_smoothing", text="Smoothing")
296         col.prop(fluid, "surface_subdivisions", text="Subdivisions")
297
298
299 class PHYSICS_PT_domain_particles(PhysicButtonsPanel):
300     bl_label = "Domain Particles"
301     bl_default_closed = True
302
303     def poll(self, context):
304         md = context.fluid
305         return md and (md.settings.type == 'DOMAIN')
306
307     def draw(self, context):
308         layout = self.layout
309
310         fluid = context.fluid.settings
311
312         col = layout.column(align=True)
313         col.prop(fluid, "tracer_particles")
314         col.prop(fluid, "generate_particles")
315
316
317 classes = [
318     PHYSICS_PT_fluid,
319     PHYSICS_PT_domain_gravity,
320     PHYSICS_PT_domain_boundary,
321     PHYSICS_PT_domain_particles]
322
323
324 def register():
325     register = bpy.types.register
326     for cls in classes:
327         register(cls)
328
329
330 def unregister():
331     unregister = bpy.types.unregister
332     for cls in classes:
333         unregister(cls)
334
335 if __name__ == "__main__":
336     register()