Removed UI for point cache users.
[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 (
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.prop(surf, "name", text="", emboss=False, 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 == '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=1)
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, "surface_format")
91
92                     col = layout.column()
93                     if surface.surface_format != 'VERTEX':
94                         col.label(text="Quality:")
95                         col.prop(surface, "image_resolution")
96                     col.prop(surface, "use_antialiasing")
97
98                     col = layout.column()
99                     col.label(text="Frames:")
100                     split = col.split()
101
102                     col = split.column(align=True)
103                     col.prop(surface, "frame_start", text="Start")
104                     col.prop(surface, "frame_end", text="End")
105
106                     split.prop(surface, "frame_substeps")
107
108         elif md.ui_type == 'BRUSH':
109             brush = md.brush_settings
110             use_shading_nodes = context.scene.render.use_shading_nodes
111
112             if brush is None:
113                 layout.operator("dpaint.type_toggle", text="Add Brush").type = 'BRUSH'
114             else:
115                 layout.operator("dpaint.type_toggle", text="Remove Brush", icon='X').type = 'BRUSH'
116
117                 split = layout.split()
118
119                 col = split.column()
120                 col.prop(brush, "use_absolute_alpha")
121                 col.prop(brush, "use_paint_erase")
122                 col.prop(brush, "paint_wetness", text="Wetness")
123
124                 col = split.column()
125                 if not use_shading_nodes:
126                     col.prop(brush, "use_material")
127                 if brush.use_material and not use_shading_nodes:
128                     col.prop(brush, "material", text="")
129                     col.prop(brush, "paint_alpha", text="Alpha Factor")
130                 else:
131                     col.prop(brush, "paint_color", text="")
132                     col.prop(brush, "paint_alpha", text="Alpha")
133
134
135 class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, Panel):
136     bl_label = "Dynamic Paint Advanced"
137
138     @classmethod
139     def poll(cls, context):
140         md = context.dynamic_paint
141         rd = context.scene.render
142         return md and md.ui_type == 'CANVAS' and md.canvas_settings and md.canvas_settings.canvas_surfaces.active and (not rd.use_game_engine)
143
144     def draw(self, context):
145         layout = self.layout
146
147         canvas = context.dynamic_paint.canvas_settings
148         surface = canvas.canvas_surfaces.active
149
150         surface_type = surface.surface_type
151
152         layout.prop(surface, "surface_type")
153         layout.separator()
154
155         # dissolve
156         if surface_type == 'PAINT':
157             split = layout.split(percentage=0.35)
158             split.prop(surface, "use_drying", text="Dry:")
159
160             col = split.column()
161             col.active = surface.use_drying
162             split = col.split(percentage=0.7)
163             col = split.column(align=True)
164             col.prop(surface, "dry_speed", text="Time")
165             col.prop(surface, "color_dry_threshold")
166             split.prop(surface, "use_dry_log", text="Slow")
167
168         if surface_type != 'WAVE':
169             split = layout.split(percentage=0.35)
170             col = split.column()
171             if surface_type == 'WEIGHT':
172                 col.prop(surface, "use_dissolve", text="Fade:")
173             else:
174                 col.prop(surface, "use_dissolve", text="Dissolve:")
175             col = split.column()
176             col.active = surface.use_dissolve
177             split = col.split(percentage=0.7)
178             split.prop(surface, "dissolve_speed", text="Time")
179             split.prop(surface, "use_dissolve_log", text="Slow")
180
181         # per type settings
182         if surface_type == 'DISPLACE':
183             layout.prop(surface, "use_incremental_displace")
184             if surface.surface_format == 'VERTEX':
185                 row = layout.row()
186                 row.prop(surface, "depth_clamp")
187                 row.prop(surface, "displace_factor")
188
189         elif surface_type == 'WAVE':
190             layout.prop(surface, "use_wave_open_border")
191
192             split = layout.split()
193
194             col = split.column(align=True)
195             col.prop(surface, "wave_timescale")
196             col.prop(surface, "wave_speed")
197
198             col = split.column(align=True)
199             col.prop(surface, "wave_damping")
200             col.prop(surface, "wave_spring")
201             col.prop(surface, "wave_smoothness")
202
203         layout.separator()
204         layout.prop(surface, "brush_group")
205         row = layout.row()
206         row.prop(surface, "brush_influence_scale")
207         row.prop(surface, "brush_radius_scale")
208
209
210 class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel):
211     bl_label = "Dynamic Paint Output"
212     bl_options = {'DEFAULT_CLOSED'}
213
214     @classmethod
215     def poll(cls, context):
216         md = context.dynamic_paint
217         rd = context.scene.render
218         if not (md and md.ui_type == 'CANVAS' and md.canvas_settings):
219             return 0
220         surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
221         return (surface and
222                 (not (surface.surface_format == 'VERTEX' and (surface.surface_type in {'DISPLACE', 'WAVE'}))) and
223                 (not rd.use_game_engine))
224
225     def draw(self, context):
226         layout = self.layout
227
228         canvas = context.dynamic_paint.canvas_settings
229         surface = canvas.canvas_surfaces.active
230         ob = context.object
231
232         surface_type = surface.surface_type
233
234         # vertex format outputs
235         if surface.surface_format == 'VERTEX':
236             if surface_type == 'PAINT':
237                 # toggle active preview
238                 layout.prop(surface, "preview_id")
239
240                 # paint-map output
241                 row = layout.row()
242                 row.prop_search(surface, "output_name_a", ob.data, "vertex_colors", text="Paintmap layer")
243                 if surface.output_exists(object=ob, index=0):
244                     ic = 'ZOOMOUT'
245                 else:
246                     ic = 'ZOOMIN'
247
248                 row.operator("dpaint.output_toggle", icon=ic, text="").output = 'A'
249
250                 # wet-map output
251                 row = layout.row()
252                 row.prop_search(surface, "output_name_b", ob.data, "vertex_colors", text="Wetmap layer")
253                 if surface.output_exists(object=ob, index=1):
254                     ic = 'ZOOMOUT'
255                 else:
256                     ic = 'ZOOMIN'
257
258                 row.operator("dpaint.output_toggle", icon=ic, text="").output = 'B'
259
260             elif surface_type == 'WEIGHT':
261                 row = layout.row()
262                 row.prop_search(surface, "output_name_a", ob, "vertex_groups", text="Vertex Group")
263                 if surface.output_exists(object=ob, index=0):
264                     ic = 'ZOOMOUT'
265                 else:
266                     ic = 'ZOOMIN'
267
268                 row.operator("dpaint.output_toggle", icon=ic, text="").output = 'A'
269
270         # image format outputs
271         if surface.surface_format == 'IMAGE':
272             layout.operator("dpaint.bake", text="Bake Image Sequence", icon='MOD_DYNAMICPAINT')
273             layout.prop_search(surface, "uv_layer", ob.data, "uv_textures", text="UV Map")
274             layout.separator()
275
276             layout.prop(surface, "image_output_path", text="")
277             row = layout.row()
278             row.prop(surface, "image_fileformat", text="")
279             row.prop(surface, "use_premultiply", text="Premultiply alpha")
280
281             if surface_type == 'PAINT':
282                 split = layout.split(percentage=0.4)
283                 split.prop(surface, "use_output_a", text="Paintmaps:")
284                 sub = split.row()
285                 sub.active = surface.use_output_a
286                 sub.prop(surface, "output_name_a", text="")
287
288                 split = layout.split(percentage=0.4)
289                 split.prop(surface, "use_output_b", text="Wetmaps:")
290                 sub = split.row()
291                 sub.active = surface.use_output_b
292                 sub.prop(surface, "output_name_b", text="")
293             else:
294                 col = layout.column()
295                 col.prop(surface, "output_name_a", text="Filename:")
296                 if surface_type == 'DISPLACE':
297                     col.prop(surface, "displace_type", text="Displace Type")
298                     col.prop(surface, "depth_clamp")
299                 elif surface_type == 'WAVE':
300                     col.prop(surface, "depth_clamp", text="Wave Clamp")
301
302
303 class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel):
304     bl_label = "Dynamic Paint Initial Color"
305     bl_options = {'DEFAULT_CLOSED'}
306
307     @classmethod
308     def poll(cls, context):
309         md = context.dynamic_paint
310         rd = context.scene.render
311         if not (md and md.ui_type == 'CANVAS' and md.canvas_settings):
312             return 0
313         surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
314         return (surface and surface.surface_type == 'PAINT') and (not rd.use_game_engine)
315
316     def draw(self, context):
317         layout = self.layout
318
319         canvas = context.dynamic_paint.canvas_settings
320         surface = canvas.canvas_surfaces.active
321         ob = context.object
322
323         layout.prop(surface, "init_color_type", expand=False)
324         if surface.init_color_type != 'NONE':
325             layout.separator()
326
327         # dissolve
328         if surface.init_color_type == 'COLOR':
329             layout.prop(surface, "init_color")
330
331         elif surface.init_color_type == 'TEXTURE':
332             layout.prop(surface, "init_texture")
333             layout.prop_search(surface, "init_layername", ob.data, "uv_textures", text="UV Map")
334
335         elif surface.init_color_type == 'VERTEX_COLOR':
336             layout.prop_search(surface, "init_layername", ob.data, "vertex_colors", text="Color Layer")
337
338
339 class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel):
340     bl_label = "Dynamic Paint Effects"
341     bl_options = {'DEFAULT_CLOSED'}
342
343     @classmethod
344     def poll(cls, context):
345         md = context.dynamic_paint
346         rd = context.scene.render
347         if not (md and md.ui_type == 'CANVAS' and md.canvas_settings):
348             return False
349         surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
350         return (surface and surface.surface_type == 'PAINT') and (not rd.use_game_engine)
351
352     def draw(self, context):
353         layout = self.layout
354
355         canvas = context.dynamic_paint.canvas_settings
356         surface = canvas.canvas_surfaces.active
357
358         layout.prop(surface, "effect_ui", expand=True)
359
360         if surface.effect_ui == 'SPREAD':
361             layout.prop(surface, "use_spread")
362
363             row = layout.row()
364             row.active = surface.use_spread
365             row.prop(surface, "spread_speed")
366             row.prop(surface, "color_spread_speed")
367
368         elif surface.effect_ui == 'DRIP':
369             layout.prop(surface, "use_drip")
370
371             col = layout.column()
372             col.active = surface.use_drip
373             effector_weights_ui(self, context, surface.effector_weights, 'DYNAMIC_PAINT')
374
375             layout.label(text="Surface Movement:")
376             row = layout.row()
377             row.prop(surface, "drip_velocity", slider=True)
378             row.prop(surface, "drip_acceleration", slider=True)
379
380         elif surface.effect_ui == 'SHRINK':
381             layout.prop(surface, "use_shrink")
382
383             row = layout.row()
384             row.active = surface.use_shrink
385             row.prop(surface, "shrink_speed")
386
387
388 class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel):
389     bl_label = "Dynamic Paint Source"
390
391     @classmethod
392     def poll(cls, context):
393         md = context.dynamic_paint
394         rd = context.scene.render
395         return md and md.ui_type == 'BRUSH' and md.brush_settings and (not rd.use_game_engine)
396
397     def draw(self, context):
398         layout = self.layout
399
400         brush = context.dynamic_paint.brush_settings
401         ob = context.object
402
403         split = layout.split()
404         col = split.column()
405         col.prop(brush, "paint_source")
406
407         if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE', 'POINT'}:
408             col.prop(brush, "paint_distance", text="Paint Distance")
409             split = layout.row().split(percentage=0.4)
410             sub = split.column()
411             if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE'}:
412                 sub.prop(brush, "use_proximity_project")
413             if brush.paint_source == 'VOLUME_DISTANCE':
414                 sub.prop(brush, "invert_proximity")
415                 sub.prop(brush, "use_negative_volume")
416
417             sub = split.column()
418             if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE'}:
419                 column = sub.column()
420                 column.active = brush.use_proximity_project
421                 column.prop(brush, "ray_direction")
422             sub.prop(brush, "proximity_falloff")
423             if brush.proximity_falloff == 'RAMP':
424                 col = layout.row().column()
425                 col.separator()
426                 col.prop(brush, "use_proximity_ramp_alpha", text="Only Use Alpha")
427                 col.template_color_ramp(brush, "paint_ramp", expand=True)
428
429
430 class PHYSICS_PT_dp_brush_velocity(PhysicButtonsPanel, Panel):
431     bl_label = "Dynamic Paint Velocity"
432     bl_options = {'DEFAULT_CLOSED'}
433
434     @classmethod
435     def poll(cls, context):
436         md = context.dynamic_paint
437         rd = context.scene.render
438         return md and md.ui_type == 'BRUSH' and md.brush_settings and (not rd.use_game_engine)
439
440     def draw(self, context):
441         layout = self.layout
442
443         brush = context.dynamic_paint.brush_settings
444
445         split = layout.split()
446
447         col = split.column()
448         col.prop(brush, "use_velocity_alpha")
449         col.prop(brush, "use_velocity_color")
450
451         split.prop(brush, "use_velocity_depth")
452
453         col = layout.column()
454         col.active = (brush.use_velocity_alpha or brush.use_velocity_color or brush.use_velocity_depth)
455         col.prop(brush, "velocity_max")
456         col.template_color_ramp(brush, "velocity_ramp", expand=True)
457         layout.separator()
458
459         row = layout.row()
460         row.prop(brush, "use_smudge")
461         sub = row.row()
462         sub.active = brush.use_smudge
463         sub.prop(brush, "smudge_strength")
464
465
466 class PHYSICS_PT_dp_brush_wave(PhysicButtonsPanel, Panel):
467     bl_label = "Dynamic Paint Waves"
468     bl_options = {'DEFAULT_CLOSED'}
469
470     @classmethod
471     def poll(cls, context):
472         md = context.dynamic_paint
473         rd = context.scene.render
474         return md and md.ui_type == 'BRUSH' and md.brush_settings and (not rd.use_game_engine)
475
476     def draw(self, context):
477         layout = self.layout
478
479         brush = context.dynamic_paint.brush_settings
480
481         layout.prop(brush, "wave_type")
482         if brush.wave_type != 'REFLECT':
483             row = layout.row()
484             row.prop(brush, "wave_factor")
485             row.prop(brush, "wave_clamp")
486
487
488 def register():
489     bpy.utils.register_module(__name__)
490
491
492 def unregister():
493     bpy.utils.register_module(__name__)
494
495 if __name__ == "__main__":
496     register()