Dynamic Paint:
[blender.git] / release / scripts / startup / bl_ui / properties_physics_dynamicpaint.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 from bl_ui.properties_physics_common import (
23     point_cache_ui,
24     effector_weights_ui,
25     )
26
27 class PhysicButtonsPanel():
28     bl_space_type = 'PROPERTIES'
29     bl_region_type = 'WINDOW'
30     bl_context = "physics"
31
32     @classmethod
33     def poll(cls, context):
34         ob = context.object
35         rd = context.scene.render
36         return (ob and ob.type == 'MESH') and (not rd.use_game_engine) and (context.dynamic_paint)
37
38
39 class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, bpy.types.Panel):
40     bl_label = "Dynamic Paint"
41
42     def draw(self, context):
43         layout = self.layout
44
45         md = context.dynamic_paint
46         ob = context.object
47
48         if md:
49             layout.prop(md, "dynamicpaint_type", expand=True)
50
51             if md.dynamicpaint_type == 'CANVAS':
52                 canvas = md.canvas_settings
53                 surface = canvas.canvas_surfaces.active
54                 row = layout.row()
55                 row.template_list(canvas, "canvas_surfaces", canvas.canvas_surfaces, "active_index", rows=2)
56
57                 col = row.column(align=True)
58                 col.operator("dpaint.surface_slot_add", icon='ZOOMIN', text="")
59                 col.operator("dpaint.surface_slot_remove", icon='ZOOMOUT', text="")
60                 
61                 if surface:
62                     layout.prop(surface, "name")
63                     layout.prop(surface, "surface_format", expand=False)
64                     
65                     if surface.surface_format != "VERTEX":
66                         col = layout.column()
67                         col.label(text="Quality:")
68                         col.prop(surface, "image_resolution")
69                         col.prop(surface, "use_anti_aliasing")
70                 
71                     col = layout.column()
72                     col.label(text="Frames:")
73                     split = col.split()
74                 
75                     col = split.column(align=True)
76                     col.prop(surface, "start_frame", text="Start")
77                     col.prop(surface, "end_frame", text="End")
78                 
79                     col = split.column()
80                     col.prop(surface, "substeps")
81                 
82
83             elif md.dynamicpaint_type == 'BRUSH':
84                 brush = md.brush_settings
85                 
86                 layout.prop(brush, "brush_settings_context", expand=True, icon_only=True)
87                 
88                 if (brush.brush_settings_context == "GENERAL"):
89                     split = layout.split()
90
91                     col = split.column()
92                     col.prop(brush, "absolute_alpha")
93                     col.prop(brush, "paint_erase")
94                     col.prop(brush, "paint_wetness", text="Wetness")
95                 
96                     col = split.column()
97                     sub = col.column()
98                     sub.active = (brush.paint_source != "PSYS");
99                     sub.prop(brush, "use_material")
100                     if brush.use_material and brush.paint_source != "PSYS":
101                         col.prop(brush, "material", text="")
102                         col.prop(brush, "paint_alpha", text="Alpha Factor")
103                     else:
104                         col.prop(brush, "paint_color", text="")
105                         col.prop(brush, "paint_alpha", text="Alpha")
106                 
107                 elif (brush.brush_settings_context == "WAVE"):
108                     layout.prop(brush, "wave_type")
109                     if (brush.wave_type != "REFLECT"):
110                         split = layout.split(percentage=0.6)
111                         split.prop(brush, "wave_factor")
112                 else:
113                     layout.label(text="-WIP-")
114
115
116 class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, bpy.types.Panel):
117     bl_label = "Dynamic Paint: Advanced"
118
119     @classmethod
120     def poll(cls, context):
121         md = context.dynamic_paint
122         return md and (md.dynamicpaint_type == 'CANVAS') and (context.dynamic_paint.canvas_settings.canvas_surfaces.active)
123
124     def draw(self, context):
125         layout = self.layout
126
127         canvas = context.dynamic_paint.canvas_settings
128         surface = canvas.canvas_surfaces.active
129         ob = context.object
130
131         layout.prop(surface, "surface_type", expand=False)
132         layout.separator()
133
134         if (surface.surface_type == "PAINT"):
135             layout.label(text="Wetmap drying:")
136             split = layout.split(percentage=0.8)
137             split.prop(surface, "dry_speed", text="Dry Time")
138             split.prop(surface, "use_dry_log", text="Slow")
139             
140         if (surface.surface_type != "WAVE"):
141             if (surface.surface_type == "DISPLACE"):
142                 layout.prop(surface, "use_dissolve", text="Dissolve:")
143             elif (surface.surface_type == "WEIGHT"):
144                 layout.prop(surface, "use_dissolve", text="Fade:")
145             else:
146                 layout.prop(surface, "use_dissolve", text="Dissolve:")
147             sub = layout.column()
148             sub.active = surface.use_dissolve
149             split = sub.split(percentage=0.8)
150             split.prop(surface, "dissolve_speed", text="Time")
151             split.prop(surface, "use_dissolve_log", text="Slow")
152             
153         if (surface.surface_type == "WAVE"):
154             layout.prop(surface, "wave_open_borders")
155             
156             split = layout.split()
157             
158             col = split.column(align=True)
159             col.prop(surface, "wave_timescale")
160             col.prop(surface, "wave_speed")
161             
162             col = split.column(align=True)
163             col.prop(surface, "wave_damping")
164             col.prop(surface, "wave_spring")
165             
166         layout.label(text="Brush Group:")
167         layout.prop(surface, "brush_group", text="")
168
169
170 class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, bpy.types.Panel):
171     bl_label = "Dynamic Paint: Output"
172     bl_options = {'DEFAULT_CLOSED'}
173
174     @classmethod
175     def poll(cls, context):
176         md = context.dynamic_paint
177         if ((not md) or (md.dynamicpaint_type != 'CANVAS')):
178             return 0
179         surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
180         return (surface and not (surface.surface_format=="VERTEX" and (surface.surface_type=="DISPLACE" or surface.surface_type=="WAVE")))
181
182     def draw(self, context):
183         layout = self.layout
184
185         canvas = context.dynamic_paint.canvas_settings
186         surface = canvas.canvas_surfaces.active
187         ob = context.object
188         
189         # vertex format outputs
190         if (surface.surface_format == "VERTEX"):
191             if (surface.surface_type == "PAINT"):
192                 row = layout.row()
193                 row.prop_search(surface, "output_name", ob.data, "vertex_colors", text="Paintmap layer: ")
194                 #col = row.column(align=True)
195                 #col.operator("dpaint.output_add", icon='ZOOMIN', text="")
196                 
197                 row = layout.row()
198                 row.prop_search(surface, "output_name2", ob.data, "vertex_colors", text="Wetmap layer: ")
199                 #col = row.column(align=True)
200                 #col.operator("dpaint.output_add", icon='ZOOMIN', text="")
201             if (surface.surface_type == "WEIGHT"):
202                 layout.prop_search(surface, "output_name", ob, "vertex_groups", text="Vertex Group: ")
203
204         # image format outputs
205         if (surface.surface_format == "IMAGE"):
206             col = layout.column()
207             col.label(text="UV layer:")
208             col.prop_search(surface, "uv_layer", ob.data, "uv_textures", text="")
209             
210             col.separator()
211             col = layout.column()
212             col.prop(surface, "image_output_path", text="Output directory")
213             col.prop(surface, "image_fileformat", text="Image Format")
214             col.separator()
215             if (surface.surface_type == "PAINT"):
216                 split = col.split()
217                 col = split.column()
218                 col.prop(surface, "do_output1", text="Output Paintmaps:")
219                 sub = split.column()
220                 sub.prop(surface, "premultiply", text="Premultiply alpha")
221                 sub.active = surface.do_output1
222                 sub = layout.column()
223                 sub.active = surface.do_output1
224                 sub.prop(surface, "output_name", text="Filename: ")
225                 
226                 col = layout.column()
227                 col.prop(surface, "do_output2", text="Output Wetmaps:")
228                 sub = col.column()
229                 sub.active = surface.do_output2
230                 sub.prop(surface, "output_name2", text="Filename: ")
231             else:
232                 col.prop(surface, "output_name", text="Filename: ")
233                 if (surface.surface_type == "DISPLACE"):
234                     col.prop(surface, "disp_type", text="Displace Type")
235             
236             layout.separator()
237             layout.operator("dpaint.bake", text="Bake Image Sequence", icon='MOD_DYNAMICPAINT')
238             if len(canvas.ui_info) != 0:
239                 layout.label(text=canvas.ui_info)
240                 
241
242 class PHYSICS_PT_dp_effects(PhysicButtonsPanel, bpy.types.Panel):
243     bl_label = "Dynamic Paint: Effects"
244     bl_options = {'DEFAULT_CLOSED'}
245
246     @classmethod
247     def poll(cls, context):
248         md = context.dynamic_paint
249         if ((not md) or (md.dynamicpaint_type != 'CANVAS')):
250             return False;
251         surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
252         return surface and (surface.surface_type == "PAINT")
253
254     def draw(self, context):
255         layout = self.layout
256
257         canvas = context.dynamic_paint.canvas_settings
258         surface = canvas.canvas_surfaces.active
259
260         layout.prop(surface, "effect_ui", expand=True)
261
262         if surface.effect_ui == "SPREAD":
263             layout.prop(surface, "use_spread")
264             col = layout.column()
265             col.active = surface.use_spread
266             col.prop(surface, "spread_speed")
267
268         elif surface.effect_ui == "DRIP":
269             layout.prop(surface, "use_drip")
270             col = layout.column()
271             col.active = surface.use_drip
272             effector_weights_ui(self, context, surface.effector_weights)
273
274         elif surface.effect_ui == "SHRINK":
275             layout.prop(surface, "use_shrink")
276             col = layout.column()
277             col.active = surface.use_shrink
278             col.prop(surface, "shrink_speed")
279                         
280
281 class PHYSICS_PT_dp_cache(PhysicButtonsPanel, bpy.types.Panel):
282     bl_label = "Dynamic Paint: Cache"
283     bl_options = {'DEFAULT_CLOSED'}
284
285     @classmethod
286     def poll(cls, context):
287         md = context.dynamic_paint
288         return md and (md.dynamicpaint_type == 'CANVAS') and \
289         (md.canvas_settings.canvas_surfaces.active) and (md.canvas_settings.canvas_surfaces.active.uses_cache)
290
291     def draw(self, context):
292         layout = self.layout
293
294         surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
295         cache = surface.point_cache
296         
297         point_cache_ui(self, context, cache, (cache.is_baked is False), 'DYNAMIC_PAINT')
298
299
300 class PHYSICS_PT_dp_advanced_brush(PhysicButtonsPanel, bpy.types.Panel):
301     bl_label = "Dynamic Paint: Advanced"
302     bl_options = {'DEFAULT_CLOSED'}
303
304     @classmethod
305     def poll(cls, context):
306         md = context.dynamic_paint
307         return md and (md.dynamicpaint_type == 'BRUSH')
308
309     def draw(self, context):
310         layout = self.layout
311
312         brush = context.dynamic_paint.brush_settings
313         ob = context.object
314                 
315         split = layout.split()
316         col = split.column()
317         col.prop(brush, "paint_source")
318
319         if brush.paint_source == "PSYS":
320             col.prop_search(brush, "psys", ob, "particle_systems", text="")
321             if brush.psys:
322                 col.label(text="Particle effect:")
323                 sub = col.column()
324                 sub.active = not brush.use_part_radius
325                 sub.prop(brush, "solid_radius", text="Solid Radius")
326                 col.prop(brush, "use_part_radius", text="Use Particle's Radius")
327                 col.prop(brush, "smooth_radius", text="Smooth radius")
328
329         elif brush.paint_source == "DISTANCE" or brush.paint_source == "VOLDIST":
330             col.prop(brush, "paint_distance", text="Paint Distance")
331             split = layout.row().split()
332             sub = split.column()
333             sub.prop(brush, "prox_facealigned")
334             sub = split.column()
335             sub.prop(brush, "prox_falloff", text="Falloff")
336             if brush.paint_source == "VOLDIST":
337                 col = layout.row().column()
338                 col.prop(brush, "prox_inverse")
339             if brush.prox_falloff == "RAMP":
340                 col = layout.row().column()
341                 col.separator()
342                 col.prop(brush, "prox_ramp_alpha", text="Only Use Alpha")
343                 col.template_color_ramp(brush, "paint_ramp", expand=True)
344
345 def register():
346     bpy.utils.register_module(__name__)
347
348
349 def unregister():
350     bpy.utils.register_module(__name__)
351
352 if __name__ == "__main__":
353     register()