remove type checks on drawing uiList's,
[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 from bpy.types import Panel, UIList
22
23 from bl_ui.properties_physics_common import (point_cache_ui,
24                                              effector_weights_ui,
25                                              )
26
27
28 class PHYSICS_UL_dynapaint_surfaces(UIList):
29     def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
30         # assert(isinstance(item, bpy.types.DynamicPaintSurface)
31         surf = item
32         sticon = layout.enum_item_icon(surf, "surface_type", surf.surface_type)
33         if self.layout_type in {'DEFAULT', 'COMPACT'}:
34             row = layout.row(align=True)
35             row.label(text="", icon_value=icon)
36             row.label(text=surf.name, icon_value=sticon)
37             row = layout.row(align=True)
38             if surf.use_color_preview:
39                 row.prop(surf, "show_preview", text="", emboss=False,
40                          icon='RESTRICT_VIEW_OFF' if surf.show_preview else 'RESTRICT_VIEW_ON')
41             row.prop(surf, "is_active", text="")
42         elif self.layout_type in {'GRID'}:
43             layout.alignment = 'CENTER'
44             row = layout.row(align=True)
45             row.label(text="", icon_value=icon)
46             row.label(text="", icon_value=sticon)
47
48
49 class PhysicButtonsPanel():
50     bl_space_type = 'PROPERTIES'
51     bl_region_type = 'WINDOW'
52     bl_context = "physics"
53
54     @classmethod
55     def poll(cls, context):
56         ob = context.object
57         rd = context.scene.render
58         return (ob and ob.type == 'MESH') and (not rd.use_game_engine) and context.dynamic_paint
59
60
61 class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel):
62     bl_label = "Dynamic Paint"
63
64     def draw(self, context):
65         layout = self.layout
66
67         md = context.dynamic_paint
68
69         layout.prop(md, "ui_type", expand=True)
70
71         if md.ui_type == 'CANVAS':
72             canvas = md.canvas_settings
73
74             if canvas is None:
75                 layout.operator("dpaint.type_toggle", text="Add Canvas").type = 'CANVAS'
76             else:
77                 layout.operator("dpaint.type_toggle", text="Remove Canvas", icon='X').type = 'CANVAS'
78
79                 surface = canvas.canvas_surfaces.active
80
81                 row = layout.row()
82                 row.template_list("PHYSICS_UL_dynapaint_surfaces", "", canvas, "canvas_surfaces",
83                                    canvas.canvas_surfaces, "active_index", rows=2)
84
85                 col = row.column(align=True)
86                 col.operator("dpaint.surface_slot_add", icon='ZOOMIN', text="")
87                 col.operator("dpaint.surface_slot_remove", icon='ZOOMOUT', text="")
88
89                 if surface:
90                     layout.prop(surface, "name")
91                     layout.prop(surface, "surface_format")
92
93                     col = layout.column()
94                     if surface.surface_format != 'VERTEX':
95                         col.label(text="Quality:")
96                         col.prop(surface, "image_resolution")
97                     col.prop(surface, "use_antialiasing")
98
99                     col = layout.column()
100                     col.label(text="Frames:")
101                     split = col.split()
102
103                     col = split.column(align=True)
104                     col.prop(surface, "frame_start", text="Start")
105                     col.prop(surface, "frame_end", text="End")
106
107                     split.prop(surface, "frame_substeps")
108
109         elif md.ui_type == 'BRUSH':
110             brush = md.brush_settings
111             engine = context.scene.render.engine
112
113             if brush is None:
114                 layout.operator("dpaint.type_toggle", text="Add Brush").type = 'BRUSH'
115             else:
116                 layout.operator("dpaint.type_toggle", text="Remove Brush", icon='X').type = 'BRUSH'
117
118                 split = layout.split()
119
120                 col = split.column()
121                 col.prop(brush, "use_absolute_alpha")
122                 col.prop(brush, "use_paint_erase")
123                 col.prop(brush, "paint_wetness", text="Wetness")
124
125                 col = split.column()
126                 if engine == 'BLENDER_RENDER':
127                     sub = col.column()
128                     sub.active = (brush.paint_source != 'PARTICLE_SYSTEM')
129                     sub.prop(brush, "use_material")
130                 if brush.use_material and brush.paint_source != 'PARTICLE_SYSTEM' and engine == 'BLENDER_RENDER':
131                     col.prop(brush, "material", text="")
132                     col.prop(brush, "paint_alpha", text="Alpha Factor")
133                 else:
134                     col.prop(brush, "paint_color", text="")
135                     col.prop(brush, "paint_alpha", text="Alpha")
136
137
138 class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, Panel):
139     bl_label = "Dynamic Paint Advanced"
140
141     @classmethod
142     def poll(cls, context):
143         md = context.dynamic_paint
144         rd = context.scene.render
145         return md and md.ui_type == 'CANVAS' and md.canvas_settings and md.canvas_settings.canvas_surfaces.active and (not rd.use_game_engine)
146
147     def draw(self, context):
148         layout = self.layout
149
150         canvas = context.dynamic_paint.canvas_settings
151         surface = canvas.canvas_surfaces.active
152
153         surface_type = surface.surface_type
154
155         layout.prop(surface, "surface_type")
156         layout.separator()
157
158         # dissolve
159         if surface_type == 'PAINT':
160             split = layout.split(percentage=0.35)
161             split.prop(surface, "use_drying", text="Dry:")
162
163             col = split.column()
164             col.active = surface.use_drying
165             split = col.split(percentage=0.7)
166             col = split.column(align=True)
167             col.prop(surface, "dry_speed", text="Time")
168             col.prop(surface, "color_dry_threshold")
169             split.prop(surface, "use_dry_log", text="Slow")
170
171         if surface_type != 'WAVE':
172             split = layout.split(percentage=0.35)
173             col = split.column()
174             if surface_type == 'WEIGHT':
175                 col.prop(surface, "use_dissolve", text="Fade:")
176             else:
177                 col.prop(surface, "use_dissolve", text="Dissolve:")
178             col = split.column()
179             col.active = surface.use_dissolve
180             split = col.split(percentage=0.7)
181             split.prop(surface, "dissolve_speed", text="Time")
182             split.prop(surface, "use_dissolve_log", text="Slow")
183
184         # per type settings
185         if surface_type == 'DISPLACE':
186             layout.prop(surface, "use_incremental_displace")
187             if surface.surface_format == 'VERTEX':
188                 row = layout.row()
189                 row.prop(surface, "depth_clamp")
190                 row.prop(surface, "displace_factor")
191
192         elif surface_type == 'WAVE':
193             layout.prop(surface, "use_wave_open_border")
194
195             split = layout.split()
196
197             col = split.column(align=True)
198             col.prop(surface, "wave_timescale")
199             col.prop(surface, "wave_speed")
200
201             col = split.column(align=True)
202             col.prop(surface, "wave_damping")
203             col.prop(surface, "wave_spring")
204
205         layout.separator()
206         layout.prop(surface, "brush_group")
207         row = layout.row()
208         row.prop(surface, "brush_influence_scale")
209         row.prop(surface, "brush_radius_scale")
210
211
212 class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel):
213     bl_label = "Dynamic Paint Output"
214     bl_options = {'DEFAULT_CLOSED'}
215
216     @classmethod
217     def poll(cls, context):
218         md = context.dynamic_paint
219         rd = context.scene.render
220         if not (md and md.ui_type == 'CANVAS' and md.canvas_settings):
221             return 0
222         surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
223         return (surface and
224                 (not (surface.surface_format == 'VERTEX' and (surface.surface_type in {'DISPLACE', 'WAVE'}))) and
225                 (not rd.use_game_engine))
226
227     def draw(self, context):
228         layout = self.layout
229
230         canvas = context.dynamic_paint.canvas_settings
231         surface = canvas.canvas_surfaces.active
232         ob = context.object
233
234         surface_type = surface.surface_type
235
236         # vertex format outputs
237         if surface.surface_format == 'VERTEX':
238             if surface_type == 'PAINT':
239                  # toggle active preview
240                 layout.prop(surface, "preview_id")
241
242                 # paint-map output
243                 row = layout.row()
244                 row.prop_search(surface, "output_name_a", ob.data, "vertex_colors", text="Paintmap layer:")
245                 if surface.output_exists(object=ob, index=0):
246                     ic = 'ZOOMOUT'
247                 else:
248                     ic = 'ZOOMIN'
249
250                 row.operator("dpaint.output_toggle", icon=ic, text="").output = 'A'
251
252                 # wet-map output
253                 row = layout.row()
254                 row.prop_search(surface, "output_name_b", ob.data, "vertex_colors", text="Wetmap layer:")
255                 if surface.output_exists(object=ob, index=1):
256                     ic = 'ZOOMOUT'
257                 else:
258                     ic = 'ZOOMIN'
259
260                 row.operator("dpaint.output_toggle", icon=ic, text="").output = 'B'
261
262             elif surface_type == 'WEIGHT':
263                 row = layout.row()
264                 row.prop_search(surface, "output_name_a", ob, "vertex_groups", text="Vertex Group:")
265                 if surface.output_exists(object=ob, index=0):
266                     ic = 'ZOOMOUT'
267                 else:
268                     ic = 'ZOOMIN'
269
270                 row.operator("dpaint.output_toggle", icon=ic, text="").output = 'A'
271
272         # image format outputs
273         if surface.surface_format == 'IMAGE':
274             layout.operator("dpaint.bake", text="Bake Image Sequence", icon='MOD_DYNAMICPAINT')
275             layout.prop_search(surface, "uv_layer", ob.data, "uv_textures", text="UV Map:")
276             layout.separator()
277
278             layout.prop(surface, "image_output_path", text="")
279             row = layout.row()
280             row.prop(surface, "image_fileformat", text="")
281             row.prop(surface, "use_premultiply", text="Premultiply alpha")
282
283             if surface_type == 'PAINT':
284                 split = layout.split(percentage=0.4)
285                 split.prop(surface, "use_output_a", text="Paintmaps:")
286                 sub = split.row()
287                 sub.active = surface.use_output_a
288                 sub.prop(surface, "output_name_a", text="")
289
290                 split = layout.split(percentage=0.4)
291                 split.prop(surface, "use_output_b", text="Wetmaps:")
292                 sub = split.row()
293                 sub.active = surface.use_output_b
294                 sub.prop(surface, "output_name_b", text="")
295             else:
296                 col = layout.column()
297                 col.prop(surface, "output_name_a", text="Filename:")
298                 if surface_type == 'DISPLACE':
299                     col.prop(surface, "displace_type", text="Displace Type")
300                     col.prop(surface, "depth_clamp")
301                 elif surface_type == 'WAVE':
302                     col.prop(surface, "depth_clamp", text="Wave Clamp")
303
304
305 class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel):
306     bl_label = "Dynamic Paint Initial Color"
307     bl_options = {'DEFAULT_CLOSED'}
308
309     @classmethod
310     def poll(cls, context):
311         md = context.dynamic_paint
312         rd = context.scene.render
313         if not (md and md.ui_type == 'CANVAS' and md.canvas_settings):
314             return 0
315         surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
316         return (surface and surface.surface_type == 'PAINT') and (not rd.use_game_engine)
317
318     def draw(self, context):
319         layout = self.layout
320
321         canvas = context.dynamic_paint.canvas_settings
322         surface = canvas.canvas_surfaces.active
323         ob = context.object
324
325         layout.prop(surface, "init_color_type", expand=False)
326         layout.separator()
327
328         # dissolve
329         if surface.init_color_type == 'COLOR':
330             layout.prop(surface, "init_color")
331
332         elif surface.init_color_type == 'TEXTURE':
333             layout.prop(surface, "init_texture")
334             layout.prop_search(surface, "init_layername", ob.data, "uv_textures", text="UV Map:")
335
336         elif surface.init_color_type == 'VERTEX_COLOR':
337             layout.prop_search(surface, "init_layername", ob.data, "vertex_colors", text="Color Layer:")
338
339
340 class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel):
341     bl_label = "Dynamic Paint Effects"
342     bl_options = {'DEFAULT_CLOSED'}
343
344     @classmethod
345     def poll(cls, context):
346         md = context.dynamic_paint
347         rd = context.scene.render
348         if not (md and md.ui_type == 'CANVAS' and md.canvas_settings):
349             return False
350         surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
351         return (surface and surface.surface_type == 'PAINT') and (not rd.use_game_engine)
352
353     def draw(self, context):
354         layout = self.layout
355
356         canvas = context.dynamic_paint.canvas_settings
357         surface = canvas.canvas_surfaces.active
358
359         layout.prop(surface, "effect_ui", expand=True)
360
361         if surface.effect_ui == 'SPREAD':
362             layout.prop(surface, "use_spread")
363
364             row = layout.row()
365             row.active = surface.use_spread
366             row.prop(surface, "spread_speed")
367             row.prop(surface, "color_spread_speed")
368
369         elif surface.effect_ui == 'DRIP':
370             layout.prop(surface, "use_drip")
371
372             col = layout.column()
373             col.active = surface.use_drip
374             effector_weights_ui(self, context, surface.effector_weights, 'DYNAMIC_PAINT')
375
376             layout.label(text="Surface Movement:")
377             row = layout.row()
378             row.prop(surface, "drip_velocity", slider=True)
379             row.prop(surface, "drip_acceleration", slider=True)
380
381         elif surface.effect_ui == 'SHRINK':
382             layout.prop(surface, "use_shrink")
383
384             row = layout.row()
385             row.active = surface.use_shrink
386             row.prop(surface, "shrink_speed")
387
388
389 class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel):
390     bl_label = "Dynamic Paint Cache"
391     bl_options = {'DEFAULT_CLOSED'}
392
393     @classmethod
394     def poll(cls, context):
395         md = context.dynamic_paint
396         rd = context.scene.render
397         return (md and
398                 md.ui_type == 'CANVAS' and
399                 md.canvas_settings and
400                 md.canvas_settings.canvas_surfaces.active and
401                 md.canvas_settings.canvas_surfaces.active.is_cache_user and
402                 (not rd.use_game_engine))
403
404     def draw(self, context):
405         surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
406         cache = surface.point_cache
407
408         point_cache_ui(self, context, cache, (cache.is_baked is False), 'DYNAMIC_PAINT')
409
410
411 class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel):
412     bl_label = "Dynamic Paint Source"
413
414     @classmethod
415     def poll(cls, context):
416         md = context.dynamic_paint
417         rd = context.scene.render
418         return md and md.ui_type == 'BRUSH' and md.brush_settings and (not rd.use_game_engine)
419
420     def draw(self, context):
421         layout = self.layout
422
423         brush = context.dynamic_paint.brush_settings
424         ob = context.object
425
426         split = layout.split()
427         col = split.column()
428         col.prop(brush, "paint_source")
429
430         if brush.paint_source == 'PARTICLE_SYSTEM':
431             col.prop_search(brush, "particle_system", ob, "particle_systems", text="")
432             if brush.particle_system:
433                 col.label(text="Particle effect:")
434                 sub = col.column()
435                 sub.active = not brush.use_particle_radius
436                 sub.prop(brush, "solid_radius", text="Solid Radius")
437                 col.prop(brush, "use_particle_radius", text="Use Particle's Radius")
438                 col.prop(brush, "smooth_radius", text="Smooth radius")
439
440         if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE', 'POINT'}:
441             col.prop(brush, "paint_distance", text="Paint Distance")
442             split = layout.row().split(percentage=0.4)
443             sub = split.column()
444             if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE'}:
445                 sub.prop(brush, "use_proximity_project")
446             if brush.paint_source == 'VOLUME_DISTANCE':
447                 sub.prop(brush, "invert_proximity")
448                 sub.prop(brush, "use_negative_volume")
449
450             sub = split.column()
451             if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE'}:
452                 column = sub.column()
453                 column.active = brush.use_proximity_project
454                 column.prop(brush, "ray_direction")
455             sub.prop(brush, "proximity_falloff")
456             if brush.proximity_falloff == 'RAMP':
457                 col = layout.row().column()
458                 col.separator()
459                 col.prop(brush, "use_proximity_ramp_alpha", text="Only Use Alpha")
460                 col.template_color_ramp(brush, "paint_ramp", expand=True)
461
462
463 class PHYSICS_PT_dp_brush_velocity(PhysicButtonsPanel, Panel):
464     bl_label = "Dynamic Paint Velocity"
465     bl_options = {'DEFAULT_CLOSED'}
466
467     @classmethod
468     def poll(cls, context):
469         md = context.dynamic_paint
470         rd = context.scene.render
471         return md and md.ui_type == 'BRUSH' and md.brush_settings and (not rd.use_game_engine)
472
473     def draw(self, context):
474         layout = self.layout
475
476         brush = context.dynamic_paint.brush_settings
477
478         split = layout.split()
479
480         col = split.column()
481         col.prop(brush, "use_velocity_alpha")
482         col.prop(brush, "use_velocity_color")
483
484         split.prop(brush, "use_velocity_depth")
485
486         col = layout.column()
487         col.active = (brush.use_velocity_alpha or brush.use_velocity_color or brush.use_velocity_depth)
488         col.prop(brush, "velocity_max")
489         col.template_color_ramp(brush, "velocity_ramp", expand=True)
490         layout.separator()
491
492         row = layout.row()
493         row.prop(brush, "use_smudge")
494         sub = row.row()
495         sub.active = brush.use_smudge
496         sub.prop(brush, "smudge_strength")
497
498
499 class PHYSICS_PT_dp_brush_wave(PhysicButtonsPanel, Panel):
500     bl_label = "Dynamic Paint Waves"
501     bl_options = {'DEFAULT_CLOSED'}
502
503     @classmethod
504     def poll(cls, context):
505         md = context.dynamic_paint
506         rd = context.scene.render
507         return md and md.ui_type == 'BRUSH' and md.brush_settings and (not rd.use_game_engine)
508
509     def draw(self, context):
510         layout = self.layout
511
512         brush = context.dynamic_paint.brush_settings
513
514         layout.prop(brush, "wave_type")
515         if brush.wave_type != 'REFLECT':
516             row = layout.row()
517             row.prop(brush, "wave_factor")
518             row.prop(brush, "wave_clamp")
519
520
521 def register():
522     bpy.utils.register_module(__name__)
523
524
525 def unregister():
526     bpy.utils.register_module(__name__)
527
528 if __name__ == "__main__":
529     register()