1 # ##### BEGIN GPL LICENSE BLOCK #####
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.
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.
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.
17 # ##### END GPL LICENSE BLOCK #####
22 from bpy.types import Panel
24 from .properties_physics_common import (
30 class PhysicButtonsPanel():
31 bl_space_type = 'PROPERTIES'
32 bl_region_type = 'WINDOW'
33 bl_context = "physics"
36 def poll(cls, context):
38 rd = context.scene.render
39 return (ob and ob.type == 'MESH') and (not rd.use_game_engine) and context.dynamic_paint
42 class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel):
43 bl_label = "Dynamic Paint"
45 def draw(self, context):
48 md = context.dynamic_paint
50 layout.prop(md, "ui_type", expand=True)
52 if md.ui_type == 'CANVAS':
53 canvas = md.canvas_settings
56 layout.operator("dpaint.type_toggle", text="Add Canvas").type = 'CANVAS'
58 layout.operator("dpaint.type_toggle", text="Remove Canvas", icon='X').type = 'CANVAS'
60 surface = canvas.canvas_surfaces.active
63 row.template_list(canvas, "canvas_surfaces", canvas.canvas_surfaces, "active_index", rows=2)
65 col = row.column(align=True)
66 col.operator("dpaint.surface_slot_add", icon='ZOOMIN', text="")
67 col.operator("dpaint.surface_slot_remove", icon='ZOOMOUT', text="")
70 layout.prop(surface, "name")
71 layout.prop(surface, "surface_format")
74 if surface.surface_format != 'VERTEX':
75 col.label(text="Quality:")
76 col.prop(surface, "image_resolution")
77 col.prop(surface, "use_antialiasing")
80 col.label(text="Frames:")
83 col = split.column(align=True)
84 col.prop(surface, "frame_start", text="Start")
85 col.prop(surface, "frame_end", text="End")
87 split.prop(surface, "frame_substeps")
89 elif md.ui_type == 'BRUSH':
90 brush = md.brush_settings
91 engine = context.scene.render.engine
94 layout.operator("dpaint.type_toggle", text="Add Brush").type = 'BRUSH'
96 layout.operator("dpaint.type_toggle", text="Remove Brush", icon='X').type = 'BRUSH'
98 split = layout.split()
101 col.prop(brush, "use_absolute_alpha")
102 col.prop(brush, "use_paint_erase")
103 col.prop(brush, "paint_wetness", text="Wetness")
106 if engine == 'BLENDER_RENDER':
108 sub.active = (brush.paint_source != 'PARTICLE_SYSTEM')
109 sub.prop(brush, "use_material")
110 if brush.use_material and brush.paint_source != 'PARTICLE_SYSTEM' and engine == 'BLENDER_RENDER':
111 col.prop(brush, "material", text="")
112 col.prop(brush, "paint_alpha", text="Alpha Factor")
114 col.prop(brush, "paint_color", text="")
115 col.prop(brush, "paint_alpha", text="Alpha")
118 class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, Panel):
119 bl_label = "Dynamic Paint Advanced"
122 def poll(cls, context):
123 md = context.dynamic_paint
124 return md and md.ui_type == 'CANVAS' and md.canvas_settings and md.canvas_settings.canvas_surfaces.active
126 def draw(self, context):
129 canvas = context.dynamic_paint.canvas_settings
130 surface = canvas.canvas_surfaces.active
132 surface_type = surface.surface_type
134 layout.prop(surface, "surface_type")
138 if surface_type == 'PAINT':
139 split = layout.split(percentage=0.35)
140 split.label(text="Wetmap drying:")
143 split = col.split(percentage=0.7)
144 split.prop(surface, "dry_speed", text="Time")
145 split.prop(surface, "use_dry_log", text="Slow")
147 if surface_type != 'WAVE':
148 split = layout.split(percentage=0.35)
150 if surface_type == 'WEIGHT':
151 col.prop(surface, "use_dissolve", text="Fade:")
153 col.prop(surface, "use_dissolve", text="Dissolve:")
155 col.active = surface.use_dissolve
156 split = col.split(percentage=0.7)
157 split.prop(surface, "dissolve_speed", text="Time")
158 split.prop(surface, "use_dissolve_log", text="Slow")
161 if surface_type == 'DISPLACE':
162 layout.prop(surface, "use_incremental_displace")
163 if surface.surface_format == 'VERTEX':
165 row.prop(surface, "depth_clamp")
166 row.prop(surface, "displace_factor")
168 elif surface_type == 'WAVE':
169 layout.prop(surface, "use_wave_open_border")
171 split = layout.split()
173 col = split.column(align=True)
174 col.prop(surface, "wave_timescale")
175 col.prop(surface, "wave_speed")
177 col = split.column(align=True)
178 col.prop(surface, "wave_damping")
179 col.prop(surface, "wave_spring")
182 layout.prop(surface, "brush_group", text="Brush Group")
185 class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel):
186 bl_label = "Dynamic Paint Output"
187 bl_options = {'DEFAULT_CLOSED'}
190 def poll(cls, context):
191 md = context.dynamic_paint
192 if not (md and md.ui_type == 'CANVAS' and md.canvas_settings):
194 surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
195 return surface and not (surface.surface_format == 'VERTEX' and (surface.surface_type in {'DISPLACE', 'WAVE'}))
197 def draw(self, context):
200 canvas = context.dynamic_paint.canvas_settings
201 surface = canvas.canvas_surfaces.active
204 surface_type = surface.surface_type
206 # vertex format outputs
207 if surface.surface_format == 'VERTEX':
208 if surface_type == 'PAINT':
209 # toggle active preview
210 layout.prop(surface, "preview_id")
214 row.prop_search(surface, "output_name_a", ob.data, "vertex_colors", text="Paintmap layer: ")
215 if surface.output_exists(object=ob, index=0):
220 row.operator("dpaint.output_toggle", icon=ic, text="").output = 'A'
224 row.prop_search(surface, "output_name_b", ob.data, "vertex_colors", text="Wetmap layer: ")
225 if surface.output_exists(object=ob, index=1):
230 row.operator("dpaint.output_toggle", icon=ic, text="").output = 'B'
232 elif surface_type == 'WEIGHT':
234 row.prop_search(surface, "output_name_a", ob, "vertex_groups", text="Vertex Group: ")
235 if surface.output_exists(object=ob, index=0):
240 row.operator("dpaint.output_toggle", icon=ic, text="").output = 'A'
242 # image format outputs
243 if surface.surface_format == 'IMAGE':
244 layout.operator("dpaint.bake", text="Bake Image Sequence", icon='MOD_DYNAMICPAINT')
245 layout.prop_search(surface, "uv_layer", ob.data, "uv_textures", text="UV layer:")
248 layout.prop(surface, "image_output_path", text="")
250 row.prop(surface, "image_fileformat", text="")
251 row.prop(surface, "use_premultiply", text="Premultiply alpha")
253 if surface_type == 'PAINT':
254 split = layout.split(percentage=0.4)
255 split.prop(surface, "use_output_a", text="Paintmaps:")
257 sub.active = surface.use_output_a
258 sub.prop(surface, "output_name_a", text="")
260 split = layout.split(percentage=0.4)
261 split.prop(surface, "use_output_b", text="Wetmaps:")
263 sub.active = surface.use_output_b
264 sub.prop(surface, "output_name_b", text="")
266 col = layout.column()
267 col.prop(surface, "output_name_a", text="Filename: ")
268 if surface_type == 'DISPLACE':
269 col.prop(surface, "displace_type", text="Displace Type")
270 col.prop(surface, "depth_clamp")
271 elif surface_type == 'WAVE':
272 col.prop(surface, "depth_clamp", text="Wave Clamp")
275 class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel):
276 bl_label = "Dynamic Paint Initial Color"
277 bl_options = {'DEFAULT_CLOSED'}
280 def poll(cls, context):
281 md = context.dynamic_paint
282 if not (md and md.ui_type == 'CANVAS' and md.canvas_settings):
284 surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
285 return (surface and surface.surface_type == 'PAINT')
287 def draw(self, context):
290 canvas = context.dynamic_paint.canvas_settings
291 surface = canvas.canvas_surfaces.active
294 layout.prop(surface, "init_color_type", expand=False)
298 if surface.init_color_type == 'COLOR':
299 layout.prop(surface, "init_color")
301 elif surface.init_color_type == 'TEXTURE':
302 layout.prop(surface, "init_texture")
303 layout.prop_search(surface, "init_layername", ob.data, "uv_textures", text="UV Layer:")
305 elif surface.init_color_type == 'VERTEX_COLOR':
306 layout.prop_search(surface, "init_layername", ob.data, "vertex_colors", text="Color Layer: ")
309 class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel):
310 bl_label = "Dynamic Paint Effects"
311 bl_options = {'DEFAULT_CLOSED'}
314 def poll(cls, context):
315 md = context.dynamic_paint
316 if not (md and md.ui_type == 'CANVAS' and md.canvas_settings):
318 surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
319 return (surface and surface.surface_type == 'PAINT')
321 def draw(self, context):
324 canvas = context.dynamic_paint.canvas_settings
325 surface = canvas.canvas_surfaces.active
327 layout.prop(surface, "effect_ui", expand=True)
329 if surface.effect_ui == 'SPREAD':
330 layout.prop(surface, "use_spread")
333 row.active = surface.use_spread
334 row.prop(surface, "spread_speed")
335 row.prop(surface, "color_spread_speed")
337 elif surface.effect_ui == 'DRIP':
338 layout.prop(surface, "use_drip")
340 col = layout.column()
341 col.active = surface.use_drip
342 effector_weights_ui(self, context, surface.effector_weights)
344 layout.label(text="Surface Movement:")
346 row.prop(surface, "drip_velocity", slider=True)
347 row.prop(surface, "drip_acceleration", slider=True)
349 elif surface.effect_ui == 'SHRINK':
350 layout.prop(surface, "use_shrink")
353 row.active = surface.use_shrink
354 row.prop(surface, "shrink_speed")
357 class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel):
358 bl_label = "Dynamic Paint Cache"
359 bl_options = {'DEFAULT_CLOSED'}
362 def poll(cls, context):
363 md = context.dynamic_paint
365 md.ui_type == 'CANVAS' and
366 md.canvas_settings and
367 md.canvas_settings.canvas_surfaces.active and
368 md.canvas_settings.canvas_surfaces.active.is_cache_user)
370 def draw(self, context):
371 surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
372 cache = surface.point_cache
374 point_cache_ui(self, context, cache, (cache.is_baked is False), 'DYNAMIC_PAINT')
377 class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel):
378 bl_label = "Dynamic Paint Source"
381 def poll(cls, context):
382 md = context.dynamic_paint
383 return md and md.ui_type == 'BRUSH' and md.brush_settings
385 def draw(self, context):
388 brush = context.dynamic_paint.brush_settings
391 split = layout.split()
393 col.prop(brush, "paint_source")
395 if brush.paint_source == 'PARTICLE_SYSTEM':
396 col.prop_search(brush, "particle_system", ob, "particle_systems", text="")
397 if brush.particle_system:
398 col.label(text="Particle effect:")
400 sub.active = not brush.use_particle_radius
401 sub.prop(brush, "solid_radius", text="Solid Radius")
402 col.prop(brush, "use_particle_radius", text="Use Particle's Radius")
403 col.prop(brush, "smooth_radius", text="Smooth radius")
405 if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE', 'POINT'}:
406 col.prop(brush, "paint_distance", text="Paint Distance")
407 split = layout.row().split(percentage=0.4)
409 if brush.paint_source == 'DISTANCE':
410 sub.prop(brush, "use_proximity_project")
411 elif brush.paint_source == 'VOLUME_DISTANCE':
412 sub.prop(brush, "invert_proximity")
413 sub.prop(brush, "use_negative_volume")
416 if brush.paint_source == 'DISTANCE':
417 column = sub.column()
418 column.active = brush.use_proximity_project
419 column.prop(brush, "ray_direction")
420 sub.prop(brush, "proximity_falloff")
421 if brush.proximity_falloff == 'RAMP':
422 col = layout.row().column()
424 col.prop(brush, "use_proximity_ramp_alpha", text="Only Use Alpha")
425 col.template_color_ramp(brush, "paint_ramp", expand=True)
428 class PHYSICS_PT_dp_brush_velocity(PhysicButtonsPanel, Panel):
429 bl_label = "Dynamic Paint Velocity"
430 bl_options = {'DEFAULT_CLOSED'}
433 def poll(cls, context):
434 md = context.dynamic_paint
435 return md and md.ui_type == 'BRUSH' and md.brush_settings
437 def draw(self, context):
440 brush = context.dynamic_paint.brush_settings
442 split = layout.split()
445 col.prop(brush, "use_velocity_alpha")
446 col.prop(brush, "use_velocity_color")
448 split.prop(brush, "use_velocity_depth")
450 col = layout.column()
451 col.active = (brush.use_velocity_alpha or brush.use_velocity_color or brush.use_velocity_depth)
452 col.prop(brush, "velocity_max")
453 col.template_color_ramp(brush, "velocity_ramp", expand=True)
457 row.prop(brush, "use_smudge")
459 sub.active = brush.use_smudge
460 sub.prop(brush, "smudge_strength")
463 class PHYSICS_PT_dp_brush_wave(PhysicButtonsPanel, Panel):
464 bl_label = "Dynamic Paint Waves"
465 bl_options = {'DEFAULT_CLOSED'}
468 def poll(cls, context):
469 md = context.dynamic_paint
470 return md and md.ui_type == 'BRUSH' and md.brush_settings
472 def draw(self, context):
475 brush = context.dynamic_paint.brush_settings
477 layout.prop(brush, "wave_type")
478 if brush.wave_type != 'REFLECT':
480 row.prop(brush, "wave_factor")
481 row.prop(brush, "wave_clamp")
485 bpy.utils.register_module(__name__)
489 bpy.utils.register_module(__name__)
491 if __name__ == "__main__":