diff options
Diffstat (limited to 'intern/cycles/blender/addon/ui.py')
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 990 |
1 files changed, 330 insertions, 660 deletions
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 707f8756f6f..bd2d5437f8f 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -17,12 +17,13 @@ # <pep8 compliant> import bpy +from bpy_extras.node_utils import find_node_input, find_output_node from bpy.types import ( - Panel, - Menu, - Operator, - ) + Panel, + Menu, + Operator, +) class CYCLES_MT_sampling_presets(Menu): @@ -49,8 +50,7 @@ class CyclesButtonsPanel: @classmethod def poll(cls, context): - rd = context.scene.render - return rd.engine in cls.COMPAT_ENGINES + return context.engine in cls.COMPAT_ENGINES def get_device_type(context): @@ -86,6 +86,7 @@ def use_sample_all_lights(context): return cscene.sample_all_lights_direct or cscene.sample_all_lights_indirect + def show_device_active(context): cscene = context.scene.cycles if cscene.device != 'GPU': @@ -145,6 +146,7 @@ class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = False scene = context.scene cscene = scene.cycles @@ -154,62 +156,51 @@ class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel): row.operator("render.cycles_sampling_preset_add", text="", icon="ZOOMIN") row.operator("render.cycles_sampling_preset_add", text="", icon="ZOOMOUT").remove_active = True - row = layout.row() - sub = row.row() - sub.prop(cscene, "progressive", text="") - row.prop(cscene, "use_square_samples") - - split = layout.split() - - col = split.column() - sub = col.column(align=True) - sub.label("Settings:") + layout.use_property_split = True - seed_sub = sub.row(align=True) - seed_sub.prop(cscene, "seed") - seed_sub.prop(cscene, "use_animated_seed", text="", icon="TIME") - - sub.prop(cscene, "sample_clamp_direct") - sub.prop(cscene, "sample_clamp_indirect") - sub.prop(cscene, "light_sampling_threshold") + layout.prop(cscene, "progressive") if cscene.progressive == 'PATH' or use_branched_path(context) is False: - col = split.column() - sub = col.column(align=True) - sub.label(text="Samples:") - sub.prop(cscene, "samples", text="Render") - sub.prop(cscene, "preview_samples", text="Preview") + col = layout.column(align=True) + col.prop(cscene, "samples", text="Render Samples") + col.prop(cscene, "preview_samples", text="Preview Samples") + col.prop(cscene, "use_square_samples") # Duplicate below. else: - sub.label(text="AA Samples:") - sub.prop(cscene, "aa_samples", text="Render") - sub.prop(cscene, "preview_aa_samples", text="Preview") + col = layout.column(align=True) + col.prop(cscene, "aa_samples", text="Render Samples") + col.prop(cscene, "preview_aa_samples", text="Preview Samples") - col = split.column() - sub = col.column(align=True) - sub.label(text="Samples:") - sub.prop(cscene, "diffuse_samples", text="Diffuse") - sub.prop(cscene, "glossy_samples", text="Glossy") - sub.prop(cscene, "transmission_samples", text="Transmission") - sub.prop(cscene, "ao_samples", text="AO") + col = layout.column(align=True) + col.prop(cscene, "diffuse_samples", text="Diffuse Samples") + col.prop(cscene, "glossy_samples", text="Glossy Samples") + col.prop(cscene, "transmission_samples", text="Transmission Samples") + col.prop(cscene, "ao_samples", text="AO Samples") - subsub = sub.row(align=True) - subsub.active = use_sample_all_lights(context) - subsub.prop(cscene, "mesh_light_samples", text="Mesh Light") + sub = col.row(align=True) + sub.active = use_sample_all_lights(context) + sub.prop(cscene, "mesh_light_samples", text="Mesh Light Samples") - sub.prop(cscene, "subsurface_samples", text="Subsurface") - sub.prop(cscene, "volume_samples", text="Volume") + col.prop(cscene, "subsurface_samples", text="Subsurface Samples") + col.prop(cscene, "volume_samples", text="Volume Samples") + + col.prop(cscene, "use_square_samples") # Duplicate above. col = layout.column(align=True) col.prop(cscene, "sample_all_lights_direct") col.prop(cscene, "sample_all_lights_indirect") - layout.row().prop(cscene, "sampling_pattern", text="Pattern") + col = layout.column(align=True) + col.prop(cscene, "light_sampling_threshold", text="Light Threshold") + + col = layout.column(align=True) + col.prop(cscene, "sample_clamp_direct") + col.prop(cscene, "sample_clamp_indirect") - for rl in scene.render.layers: - if rl.samples > 0: - layout.separator() - layout.row().prop(cscene, "use_layer_samples") - break + row = layout.row(align=True) + row.prop(cscene, "seed") + row.prop(cscene, "use_animated_seed", text="", icon="TIME") + + layout.row().prop(cscene, "sampling_pattern", text="Pattern") draw_samples_info(layout, context) @@ -220,56 +211,48 @@ class CYCLES_RENDER_PT_geometry(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True scene = context.scene cscene = scene.cycles ccscene = scene.cycles_curves - row = layout.row() - row.label("Volume Sampling:") - row = layout.row() - row.prop(cscene, "volume_step_size") - row.prop(cscene, "volume_max_steps") + col = layout.column(align=True) + col.prop(cscene, "volume_step_size", text="Volume Step Size") + col.prop(cscene, "volume_max_steps", text="Volume Max Steps") - layout.separator() + col.separator() if cscene.feature_set == 'EXPERIMENTAL': - layout.label("Subdivision Rate:") - split = layout.split() - col = split.column() + col = layout.column() sub = col.column(align=True) - sub.prop(cscene, "dicing_rate", text="Render") - sub.prop(cscene, "preview_dicing_rate", text="Preview") + sub.prop(cscene, "dicing_rate", text="Dicing Rate Render") + sub.prop(cscene, "preview_dicing_rate", text="Dicing Rate Preview") - col = split.column() col.prop(cscene, "offscreen_dicing_scale", text="Offscreen Scale") col.prop(cscene, "max_subdivisions") - layout.prop(cscene, "dicing_camera") + col.prop(cscene, "dicing_camera") - layout.separator() + col.separator() - layout.label("Hair:") - layout.prop(ccscene, "use_curves", text="Use Hair") + layout.prop(ccscene, "use_curves", text="Hair Rendering") col = layout.column() col.active = ccscene.use_curves - col.prop(ccscene, "primitive", text="Primitive") + col.prop(ccscene, "minimum_width", text="Min Pixels") + col.prop(ccscene, "maximum_width", text="Max Extension") col.prop(ccscene, "shape", text="Shape") - if not (ccscene.primitive in {'CURVE_SEGMENTS', 'LINE_SEGMENTS'} and ccscene.shape == 'RIBBONS'): col.prop(ccscene, "cull_backfacing", text="Cull back-faces") + col.prop(ccscene, "primitive", text="Primitive") if ccscene.primitive == 'TRIANGLES' and ccscene.shape == 'THICK': col.prop(ccscene, "resolution", text="Resolution") elif ccscene.primitive == 'CURVE_SEGMENTS': col.prop(ccscene, "subdivisions", text="Curve subdivisions") - row = col.row() - row.prop(ccscene, "minimum_width", text="Min Pixels") - row.prop(ccscene, "maximum_width", text="Max Extension") - class CYCLES_RENDER_PT_light_paths(CyclesButtonsPanel, Panel): bl_label = "Light Paths" @@ -277,6 +260,7 @@ class CYCLES_RENDER_PT_light_paths(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True scene = context.scene cscene = scene.cycles @@ -286,31 +270,18 @@ class CYCLES_RENDER_PT_light_paths(CyclesButtonsPanel, Panel): row.operator("render.cycles_integrator_preset_add", text="", icon="ZOOMIN") row.operator("render.cycles_integrator_preset_add", text="", icon="ZOOMOUT").remove_active = True - split = layout.split() - - col = split.column() - - sub = col.column(align=True) - sub.label("Transparency:") - sub.prop(cscene, "transparent_max_bounces", text="Max") - - col.separator() + col = layout.column(align=True) + col.prop(cscene, "max_bounces", text="Max Bounces") + col.prop(cscene, "transparent_max_bounces", text="Transparency") + col.prop(cscene, "diffuse_bounces", text="Diffuse") + col.prop(cscene, "glossy_bounces", text="Glossy") + col.prop(cscene, "transmission_bounces", text="Transmission") + col.prop(cscene, "volume_bounces", text="Volume") + col = layout.column() + col.prop(cscene, "blur_glossy") col.prop(cscene, "caustics_reflective") col.prop(cscene, "caustics_refractive") - col.prop(cscene, "blur_glossy") - - col = split.column() - - sub = col.column(align=True) - sub.label(text="Bounces:") - sub.prop(cscene, "max_bounces", text="Max") - - sub = col.column(align=True) - sub.prop(cscene, "diffuse_bounces", text="Diffuse") - sub.prop(cscene, "glossy_bounces", text="Glossy") - sub.prop(cscene, "transmission_bounces", text="Transmission") - sub.prop(cscene, "volume_bounces", text="Volume") class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel): @@ -324,6 +295,7 @@ class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True scene = context.scene cscene = scene.cycles @@ -356,31 +328,35 @@ class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel): class CYCLES_RENDER_PT_film(CyclesButtonsPanel, Panel): bl_label = "Film" + bl_options = {'DEFAULT_CLOSED'} def draw(self, context): layout = self.layout - + layout.use_property_split = True scene = context.scene cscene = scene.cycles - split = layout.split() - - col = split.column() + col = layout.column() col.prop(cscene, "film_exposure") - col.separator() - sub = col.column(align=True) - sub.prop(cscene, "pixel_filter_type", text="") + + layout.separator() + + col = layout.column() + col.prop(cscene, "pixel_filter_type") if cscene.pixel_filter_type != 'BOX': - sub.prop(cscene, "filter_width", text="Width") + col.prop(cscene, "filter_width") - col = split.column() + layout.separator() + + col = layout.column() col.prop(cscene, "film_transparent") - sub = col.row() + sub = col.column() sub.prop(cscene, "film_transparent_glass", text="Transparent Glass") sub.active = cscene.film_transparent - sub = col.row() - sub.prop(cscene, "film_transparent_roughness", text="Roughness Threshold") - sub.active = cscene.film_transparent and cscene.film_transparent_glass + + col = layout.column() + col.active = cscene.film_transparent and cscene.film_transparent_glass + col.prop(cscene, "film_transparent_roughness", text="Roughness Threshold") class CYCLES_RENDER_PT_performance(CyclesButtonsPanel, Panel): @@ -389,63 +365,75 @@ class CYCLES_RENDER_PT_performance(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True scene = context.scene rd = scene.render cscene = scene.cycles - split = layout.split() + col = layout.column() - col = split.column(align=True) + col = layout.column() + col.active = show_device_active(context) + col.prop(cscene, "device") + + from . import engine + if engine.with_osl() and use_cpu(context): + col.prop(cscene, "shading_system") - col.label(text="Threads:") - col.row(align=True).prop(rd, "threads_mode", expand=True) + col.separator() + + col = layout.column() + + col.row(align=True).prop(rd, "threads_mode") sub = col.column(align=True) sub.enabled = rd.threads_mode == 'FIXED' sub.prop(rd, "threads") col.separator() - sub = col.column(align=True) - sub.label(text="Tiles:") - sub.prop(cscene, "tile_order", text="") + col = layout.column() - sub.prop(rd, "tile_x", text="X") + sub = col.column(align=True) + sub.prop(rd, "tile_x", text="Tiles X") sub.prop(rd, "tile_y", text="Y") + col.prop(cscene, "tile_order", text="Order") - subsub = sub.column() - subsub.active = not rd.use_save_buffers - for rl in rd.layers: - if rl.cycles.use_denoising: - subsub.active = False - subsub.prop(cscene, "use_progressive_refine") + sub = col.column() + sub.active = not rd.use_save_buffers + for view_layer in scene.view_layers: + if view_layer.cycles.use_denoising: + sub.active = False + sub.prop(cscene, "use_progressive_refine") - col = split.column() + layout.separator() + + col = layout.column() - col.label(text="Final Render:") col.prop(rd, "use_save_buffers") col.prop(rd, "use_persistent_data", text="Persistent Images") - col.separator() + layout.separator() + + col = layout.column() - col.label(text="Acceleration structure:") col.prop(cscene, "debug_use_spatial_splits") col.prop(cscene, "debug_use_hair_bvh") - row = col.row() - row.active = not cscene.debug_use_spatial_splits - row.prop(cscene, "debug_bvh_time_steps") + sub = col.column() + sub.active = not cscene.debug_use_spatial_splits + sub.prop(cscene, "debug_bvh_time_steps") + + layout.separator() col = layout.column() - col.label(text="Viewport Resolution:") - split = col.split() - split.prop(rd, "preview_pixel_size", text="") - split.prop(cscene, "preview_start_resolution") + col.prop(rd, "preview_pixel_size", text="Viewport Pixel Size") + col.prop(cscene, "preview_start_resolution", text="Start Pixels") -class CYCLES_RENDER_PT_layer_options(CyclesButtonsPanel, Panel): - bl_label = "Layer" - bl_context = "render_layer" +class CYCLES_RENDER_PT_filter(CyclesButtonsPanel, Panel): + bl_label = "Filter" + bl_context = "view_layer" def draw(self, context): layout = self.layout @@ -453,40 +441,22 @@ class CYCLES_RENDER_PT_layer_options(CyclesButtonsPanel, Panel): scene = context.scene rd = scene.render - rl = rd.layers.active + view_layer = context.view_layer - split = layout.split() - - col = split.column() - col.prop(scene, "layers", text="Scene") - col.prop(rl, "layers_exclude", text="Exclude") - - col = split.column() - col.prop(rl, "layers", text="Layer") - col.prop(rl, "layers_zmask", text="Mask Layer") - - split = layout.split() - - col = split.column() - col.label(text="Material:") - col.prop(rl, "material_override", text="") - col.separator() - col.prop(rl, "samples") - - col = split.column() - col.prop(rl, "use_sky", "Use Environment") - col.prop(rl, "use_ao", "Use AO") - col.prop(rl, "use_solid", "Use Surfaces") - col.prop(rl, "use_strand", "Use Hair") + col = layout.column() + col.prop(view_layer, "use_sky", "Use Environment") + col.prop(view_layer, "use_ao", "Use Ambient Occlusion") + col.prop(view_layer, "use_solid", "Use Surfaces") + col.prop(view_layer, "use_strand", "Use Hair") if with_freestyle: row = col.row() - row.prop(rl, "use_freestyle", "Use Freestyle") + row.prop(view_layer, "use_freestyle", "Use Freestyle") row.active = rd.use_freestyle class CYCLES_RENDER_PT_layer_passes(CyclesButtonsPanel, Panel): bl_label = "Passes" - bl_context = "render_layer" + bl_context = "view_layer" bl_options = {'DEFAULT_CLOSED'} def draw(self, context): @@ -496,178 +466,158 @@ class CYCLES_RENDER_PT_layer_passes(CyclesButtonsPanel, Panel): scene = context.scene rd = scene.render - rl = rd.layers.active - crl = rl.cycles + view_layer = context.view_layer + cycles_view_layer = view_layer.cycles split = layout.split() col = split.column() - col.prop(rl, "use_pass_combined") - col.prop(rl, "use_pass_z") - col.prop(rl, "use_pass_mist") - col.prop(rl, "use_pass_normal") + col.prop(view_layer, "use_pass_combined") + col.prop(view_layer, "use_pass_z") + col.prop(view_layer, "use_pass_mist") + col.prop(view_layer, "use_pass_normal") row = col.row() - row.prop(rl, "use_pass_vector") + row.prop(view_layer, "use_pass_vector") row.active = not rd.use_motion_blur - col.prop(rl, "use_pass_uv") - col.prop(rl, "use_pass_object_index") - col.prop(rl, "use_pass_material_index") + col.prop(view_layer, "use_pass_uv") + col.prop(view_layer, "use_pass_object_index") + col.prop(view_layer, "use_pass_material_index") col.separator() - col.prop(rl, "use_pass_shadow") - col.prop(rl, "use_pass_ambient_occlusion") + col.prop(view_layer, "use_pass_shadow") + col.prop(view_layer, "use_pass_ambient_occlusion", text="Ambient Occlusion") col.separator() - col.prop(rl, "pass_alpha_threshold") + col.prop(view_layer, "pass_alpha_threshold") col = split.column() col.label(text="Diffuse:") row = col.row(align=True) - row.prop(rl, "use_pass_diffuse_direct", text="Direct", toggle=True) - row.prop(rl, "use_pass_diffuse_indirect", text="Indirect", toggle=True) - row.prop(rl, "use_pass_diffuse_color", text="Color", toggle=True) + row.prop(view_layer, "use_pass_diffuse_direct", text="Direct", toggle=True) + row.prop(view_layer, "use_pass_diffuse_indirect", text="Indirect", toggle=True) + row.prop(view_layer, "use_pass_diffuse_color", text="Color", toggle=True) col.label(text="Glossy:") row = col.row(align=True) - row.prop(rl, "use_pass_glossy_direct", text="Direct", toggle=True) - row.prop(rl, "use_pass_glossy_indirect", text="Indirect", toggle=True) - row.prop(rl, "use_pass_glossy_color", text="Color", toggle=True) + row.prop(view_layer, "use_pass_glossy_direct", text="Direct", toggle=True) + row.prop(view_layer, "use_pass_glossy_indirect", text="Indirect", toggle=True) + row.prop(view_layer, "use_pass_glossy_color", text="Color", toggle=True) col.label(text="Transmission:") row = col.row(align=True) - row.prop(rl, "use_pass_transmission_direct", text="Direct", toggle=True) - row.prop(rl, "use_pass_transmission_indirect", text="Indirect", toggle=True) - row.prop(rl, "use_pass_transmission_color", text="Color", toggle=True) + row.prop(view_layer, "use_pass_transmission_direct", text="Direct", toggle=True) + row.prop(view_layer, "use_pass_transmission_indirect", text="Indirect", toggle=True) + row.prop(view_layer, "use_pass_transmission_color", text="Color", toggle=True) col.label(text="Subsurface:") row = col.row(align=True) - row.prop(rl, "use_pass_subsurface_direct", text="Direct", toggle=True) - row.prop(rl, "use_pass_subsurface_indirect", text="Indirect", toggle=True) - row.prop(rl, "use_pass_subsurface_color", text="Color", toggle=True) + row.prop(view_layer, "use_pass_subsurface_direct", text="Direct", toggle=True) + row.prop(view_layer, "use_pass_subsurface_indirect", text="Indirect", toggle=True) + row.prop(view_layer, "use_pass_subsurface_color", text="Color", toggle=True) col.label(text="Volume:") row = col.row(align=True) - row.prop(crl, "use_pass_volume_direct", text="Direct", toggle=True) - row.prop(crl, "use_pass_volume_indirect", text="Indirect", toggle=True) + row.prop(cycles_view_layer, "use_pass_volume_direct", text="Direct", toggle=True) + row.prop(cycles_view_layer, "use_pass_volume_indirect", text="Indirect", toggle=True) col.separator() - col.prop(rl, "use_pass_emit", text="Emission") - col.prop(rl, "use_pass_environment") + col.prop(view_layer, "use_pass_emit", text="Emission") + col.prop(view_layer, "use_pass_environment") if context.scene.cycles.feature_set == 'EXPERIMENTAL': col.separator() sub = col.column() - sub.active = crl.use_denoising - sub.prop(crl, "denoising_store_passes", text="Denoising") + sub.active = cycles_view_layer.use_denoising + sub.prop(cycles_view_layer, "denoising_store_passes", text="Denoising") col = layout.column() - col.prop(crl, "pass_debug_render_time") + col.prop(cycles_view_layer, "pass_debug_render_time") if _cycles.with_cycles_debug: - col.prop(crl, "pass_debug_bvh_traversed_nodes") - col.prop(crl, "pass_debug_bvh_traversed_instances") - col.prop(crl, "pass_debug_bvh_intersections") - col.prop(crl, "pass_debug_ray_bounces") - - -class CYCLES_RENDER_PT_views(CyclesButtonsPanel, Panel): - bl_label = "Views" - bl_context = "render_layer" - bl_options = {'DEFAULT_CLOSED'} - - def draw_header(self, context): - rd = context.scene.render - self.layout.prop(rd, "use_multiview", text="") - - def draw(self, context): - layout = self.layout - - scene = context.scene - rd = scene.render - rv = rd.views.active - - layout.active = rd.use_multiview - basic_stereo = (rd.views_format == 'STEREO_3D') - - row = layout.row() - row.prop(rd, "views_format", expand=True) - - if basic_stereo: - row = layout.row() - row.template_list("RENDERLAYER_UL_renderviews", "name", rd, "stereo_views", rd.views, "active_index", rows=2) - - row = layout.row() - row.label(text="File Suffix:") - row.prop(rv, "file_suffix", text="") - - else: - row = layout.row() - row.template_list("RENDERLAYER_UL_renderviews", "name", rd, "views", rd.views, "active_index", rows=2) - - col = row.column(align=True) - col.operator("scene.render_view_add", icon='ZOOMIN', text="") - col.operator("scene.render_view_remove", icon='ZOOMOUT', text="") - - row = layout.row() - row.label(text="Camera Suffix:") - row.prop(rv, "camera_suffix", text="") + col.prop(cycles_view_layer, "pass_debug_bvh_traversed_nodes") + col.prop(cycles_view_layer, "pass_debug_bvh_traversed_instances") + col.prop(cycles_view_layer, "pass_debug_bvh_intersections") + col.prop(cycles_view_layer, "pass_debug_ray_bounces") class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel): bl_label = "Denoising" - bl_context = "render_layer" + bl_context = "view_layer" bl_options = {'DEFAULT_CLOSED'} def draw_header(self, context): - rd = context.scene.render - rl = rd.layers.active - crl = rl.cycles - cscene = context.scene.cycles + scene = context.scene + view_layer = context.view_layer + cycles_view_layer = view_layer.cycles + cscene = scene.cycles layout = self.layout - layout.prop(crl, "use_denoising", text="") + layout.prop(cycles_view_layer, "use_denoising", text="") def draw(self, context): layout = self.layout + layout.use_property_split = True scene = context.scene cscene = scene.cycles - rd = scene.render - rl = rd.layers.active - crl = rl.cycles + view_layer = context.view_layer + cycles_view_layer = view_layer.cycles - layout.active = crl.use_denoising + layout.active = cycles_view_layer.use_denoising - split = layout.split() + col = layout.column() + sub = col.column() + sub.prop(cycles_view_layer, "denoising_radius", text="Radius") + sub.prop(cycles_view_layer, "denoising_strength", slider=True, text="Strength") - col = split.column() sub = col.column(align=True) - sub.prop(crl, "denoising_radius", text="Radius") - sub.prop(crl, "denoising_strength", slider=True, text="Strength") + sub.prop(cycles_view_layer, "denoising_feature_strength", slider=True, text="Feature Strength") + sub.prop(cycles_view_layer, "denoising_relative_pca") - col = split.column() - sub = col.column(align=True) - sub.prop(crl, "denoising_feature_strength", slider=True, text="Feature Strength") - sub.prop(crl, "denoising_relative_pca") +# layout.use_property_split = False + """ layout.separator() - row = layout.row() - row.label(text="Diffuse:") - sub = row.row(align=True) - sub.prop(crl, "denoising_diffuse_direct", text="Direct", toggle=True) - sub.prop(crl, "denoising_diffuse_indirect", text="Indirect", toggle=True) + col = layout.column(align=True) + col.prop(cycles_view_layer, "denoising_diffuse_direct", text="Diffuse Direct") + col.prop(cycles_view_layer, "denoising_diffuse_indirect", text="Indirect") - row = layout.row() - row.label(text="Glossy:") - sub = row.row(align=True) - sub.prop(crl, "denoising_glossy_direct", text="Direct", toggle=True) - sub.prop(crl, "denoising_glossy_indirect", text="Indirect", toggle=True) + col = layout.column(align=True) + col.prop(cycles_view_layer, "denoising_glossy_direct", text="Glossy Direct") + col.prop(cycles_view_layer, "denoising_glossy_indirect", text="Indirect") - row = layout.row() - row.label(text="Transmission:") - sub = row.row(align=True) - sub.prop(crl, "denoising_transmission_direct", text="Direct", toggle=True) - sub.prop(crl, "denoising_transmission_indirect", text="Indirect", toggle=True) + col = layout.column(align=True) + col.prop(cycles_view_layer, "denoising_transmission_direct", text="Transmission Direct") + col.prop(cycles_view_layer, "denoising_transmission_indirect", text="Indirect") - row = layout.row() - row.label(text="Subsurface:") - sub = row.row(align=True) - sub.prop(crl, "denoising_subsurface_direct", text="Direct", toggle=True) - sub.prop(crl, "denoising_subsurface_indirect", text="Indirect", toggle=True) + col = layout.column(align=True) + col.prop(cycles_view_layer, "denoising_subsurface_direct", text="Subsurface Direct") + col.prop(cycles_view_layer, "denoising_subsurface_indirect", text="Indirect") + """ + + layout.use_property_split = False + + split = layout.split(percentage=0.5) + split.label(text="Diffuse") + col = split.column() + row = col.row(align=True) + row.prop(cycles_view_layer, "denoising_diffuse_direct", text="Direct", toggle=True) + row.prop(cycles_view_layer, "denoising_diffuse_indirect", text="Indirect", toggle=True) + + split = layout.split(percentage=0.5) + split.label(text="Glossy") + col = split.column() + row = col.row(align=True) + row.prop(cycles_view_layer, "denoising_glossy_direct", text="Direct", toggle=True) + row.prop(cycles_view_layer, "denoising_glossy_indirect", text="Indirect", toggle=True) + + split = layout.split(percentage=0.5) + split.label(text="Transmission") + col = split.column() + row = col.row(align=True) + row.prop(cycles_view_layer, "denoising_transmission_direct", text="Direct", toggle=True) + row.prop(cycles_view_layer, "denoising_transmission_indirect", text="Indirect", toggle=True) + + split = layout.split(percentage=0.5) + split.label(text="Subsurface") + col = split.column() + row = col.row(align=True) + row.prop(cycles_view_layer, "denoising_subsurface_direct", text="Direct", toggle=True) + row.prop(cycles_view_layer, "denoising_subsurface_indirect", text="Indirect", toggle=True) class CYCLES_PT_post_processing(CyclesButtonsPanel, Panel): @@ -676,17 +626,15 @@ class CYCLES_PT_post_processing(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True rd = context.scene.render - split = layout.split() - - col = split.column() + col = layout.column(align=True) col.prop(rd, "use_compositing") col.prop(rd, "use_sequencer") - col = split.column() - col.prop(rd, "dither_intensity", text="Dither", slider=True) + layout.prop(rd, "dither_intensity", text="Dither", slider=True) class CYCLES_CAMERA_PT_dof(CyclesButtonsPanel, Panel): @@ -916,43 +864,22 @@ class CYCLES_OT_use_shading_nodes(Operator): return {'FINISHED'} -def find_node(material, nodetype): - if material and material.node_tree: - ntree = material.node_tree - - active_output_node = None - for node in ntree.nodes: - if getattr(node, "type", None) == nodetype: - if getattr(node, "is_active_output", True): - return node - if not active_output_node: - active_output_node = node - return active_output_node - - return None - - -def find_node_input(node, name): - for input in node.inputs: - if input.name == name: - return input - - return None - - -def panel_node_draw(layout, id_data, output_type, input_name): +def panel_node_draw(layout, id_data, output_types, input_name): if not id_data.use_nodes: layout.operator("cycles.use_shading_nodes", icon='NODETREE') return False ntree = id_data.node_tree - node = find_node(id_data, output_type) - if not node: - layout.label(text="No output node") - else: + node = find_output_node(ntree, output_types) + if node: input = find_node_input(node, input_name) - layout.template_node_view(ntree, node, input) + if input: + layout.template_node_view(ntree, node, input) + else: + layout.label(text="Incompatible output node") + else: + layout.label(text="No output node") return True @@ -964,10 +891,14 @@ class CYCLES_LAMP_PT_preview(CyclesButtonsPanel, Panel): @classmethod def poll(cls, context): - return context.lamp and \ - not (context.lamp.type == 'AREA' and - context.lamp.cycles.is_portal) \ - and CyclesButtonsPanel.poll(context) + return ( + context.lamp and + not ( + context.lamp.type == 'AREA' and + context.lamp.cycles.is_portal + ) and + CyclesButtonsPanel.poll(context) + ) def draw(self, context): self.layout.template_preview(context.lamp) @@ -999,9 +930,9 @@ class CYCLES_LAMP_PT_lamp(CyclesButtonsPanel, Panel): col.prop(lamp, "shape", text="") sub = col.column(align=True) - if lamp.shape == 'SQUARE': + if lamp.shape in {'SQUARE', 'DISK'}: sub.prop(lamp, "size") - elif lamp.shape == 'RECTANGLE': + elif lamp.shape in {'RECTANGLE', 'ELLIPSE'}: sub.prop(lamp, "size", text="Size X") sub.prop(lamp, "size_y", text="Size Y") @@ -1035,13 +966,13 @@ class CYCLES_LAMP_PT_nodes(CyclesButtonsPanel, Panel): def poll(cls, context): return context.lamp and not (context.lamp.type == 'AREA' and context.lamp.cycles.is_portal) and \ - CyclesButtonsPanel.poll(context) + CyclesButtonsPanel.poll(context) def draw(self, context): layout = self.layout lamp = context.lamp - if not panel_node_draw(layout, lamp, 'OUTPUT_LAMP', 'Surface'): + if not panel_node_draw(layout, lamp, ('OUTPUT_LAMP',), 'Surface'): layout.prop(lamp, "color") @@ -1096,7 +1027,7 @@ class CYCLES_WORLD_PT_surface(CyclesButtonsPanel, Panel): world = context.world - if not panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Surface'): + if not panel_node_draw(layout, world, ('OUTPUT_WORLD',), 'Surface'): layout.prop(world, "horizon_color", text="Color") @@ -1114,7 +1045,7 @@ class CYCLES_WORLD_PT_volume(CyclesButtonsPanel, Panel): layout = self.layout world = context.world - panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Volume') + panel_node_draw(layout, world, ('OUTPUT_WORLD',), 'Volume') class CYCLES_WORLD_PT_ambient_occlusion(CyclesButtonsPanel, Panel): @@ -1151,8 +1082,8 @@ class CYCLES_WORLD_PT_mist(CyclesButtonsPanel, Panel): def poll(cls, context): if CyclesButtonsPanel.poll(context): if context.world: - for rl in context.scene.render.layers: - if rl.use_pass_mist: + for view_layer in context.scene.view_layers: + if view_layer.use_pass_mist: return True return False @@ -1259,7 +1190,7 @@ class CYCLES_MATERIAL_PT_surface(CyclesButtonsPanel, Panel): layout = self.layout mat = context.material - if not panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Surface'): + if not panel_node_draw(layout, mat, ('OUTPUT_MATERIAL', 'OUTPUT_EEVEE_MATERIAL'), 'Surface'): layout.prop(mat, "diffuse_color") @@ -1279,7 +1210,7 @@ class CYCLES_MATERIAL_PT_volume(CyclesButtonsPanel, Panel): mat = context.material # cmat = mat.cycles - panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Volume') + panel_node_draw(layout, mat, ('OUTPUT_MATERIAL', 'OUTPUT_EEVEE_MATERIAL'), 'Volume') class CYCLES_MATERIAL_PT_displacement(CyclesButtonsPanel, Panel): @@ -1295,7 +1226,7 @@ class CYCLES_MATERIAL_PT_displacement(CyclesButtonsPanel, Panel): layout = self.layout mat = context.material - panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Displacement') + panel_node_draw(layout, mat, ('OUTPUT_MATERIAL', 'OUTPUT_EEVEE_MATERIAL'), 'Displacement') class CYCLES_MATERIAL_PT_settings(CyclesButtonsPanel, Panel): @@ -1334,197 +1265,6 @@ class CYCLES_MATERIAL_PT_settings(CyclesButtonsPanel, Panel): col.prop(mat, "pass_index") -class CYCLES_MATERIAL_PT_viewport(CyclesButtonsPanel, Panel): - bl_label = "Viewport" - bl_context = "material" - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - return context.material and CyclesButtonsPanel.poll(context) - - def draw(self, context): - mat = context.material - - layout = self.layout - split = layout.split() - - col = split.column(align=True) - col.label("Color:") - col.prop(mat, "diffuse_color", text="") - col.prop(mat, "alpha") - - col.separator() - col.label("Alpha:") - col.prop(mat.game_settings, "alpha_blend", text="") - - col = split.column(align=True) - col.label("Specular:") - col.prop(mat, "specular_color", text="") - col.prop(mat, "specular_hardness", text="Hardness") - - -class CYCLES_TEXTURE_PT_context(CyclesButtonsPanel, Panel): - bl_label = "" - bl_context = "texture" - bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'CYCLES'} - - def draw(self, context): - layout = self.layout - - tex = context.texture - space = context.space_data - pin_id = space.pin_id - use_pin_id = space.use_pin_id - user = context.texture_user - - space.use_limited_texture_context = False - - if not (use_pin_id and isinstance(pin_id, bpy.types.Texture)): - pin_id = None - - if not pin_id: - layout.template_texture_user() - - if user or pin_id: - layout.separator() - - split = layout.split(percentage=0.65) - col = split.column() - - if pin_id: - col.template_ID(space, "pin_id") - else: - propname = context.texture_user_property.identifier - col.template_ID(user, propname, new="texture.new") - - if tex: - split = layout.split(percentage=0.2) - split.label(text="Type:") - split.prop(tex, "type", text="") - - -class CYCLES_TEXTURE_PT_node(CyclesButtonsPanel, Panel): - bl_label = "Node" - bl_context = "texture" - - @classmethod - def poll(cls, context): - node = context.texture_node - return node and CyclesButtonsPanel.poll(context) - - def draw(self, context): - layout = self.layout - - node = context.texture_node - ntree = node.id_data - layout.template_node_view(ntree, node, None) - - -class CYCLES_TEXTURE_PT_mapping(CyclesButtonsPanel, Panel): - bl_label = "Mapping" - bl_context = "texture" - - @classmethod - def poll(cls, context): - node = context.texture_node - # TODO(sergey): perform a faster/nicer check? - return node and hasattr(node, 'texture_mapping') and CyclesButtonsPanel.poll(context) - - def draw(self, context): - layout = self.layout - - node = context.texture_node - - mapping = node.texture_mapping - - layout.prop(mapping, "vector_type", expand=True) - - row = layout.row() - - row.column().prop(mapping, "translation") - row.column().prop(mapping, "rotation") - row.column().prop(mapping, "scale") - - layout.label(text="Projection:") - - row = layout.row() - row.prop(mapping, "mapping_x", text="") - row.prop(mapping, "mapping_y", text="") - row.prop(mapping, "mapping_z", text="") - - -class CYCLES_TEXTURE_PT_colors(CyclesButtonsPanel, Panel): - bl_label = "Color" - bl_context = "texture" - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - # node = context.texture_node - return False - # return node and CyclesButtonsPanel.poll(context) - - def draw(self, context): - layout = self.layout - - node = context.texture_node - - mapping = node.color_mapping - - split = layout.split() - - col = split.column() - col.label(text="Blend:") - col.prop(mapping, "blend_type", text="") - col.prop(mapping, "blend_factor", text="Factor") - col.prop(mapping, "blend_color", text="") - - col = split.column() - col.label(text="Adjust:") - col.prop(mapping, "brightness") - col.prop(mapping, "contrast") - col.prop(mapping, "saturation") - - layout.separator() - - layout.prop(mapping, "use_color_ramp", text="Ramp") - if mapping.use_color_ramp: - layout.template_color_ramp(mapping, "color_ramp", expand=True) - - -class CYCLES_PARTICLE_PT_textures(CyclesButtonsPanel, Panel): - bl_label = "Textures" - bl_context = "particle" - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - psys = context.particle_system - return psys and CyclesButtonsPanel.poll(context) - - def draw(self, context): - layout = self.layout - - psys = context.particle_system - part = psys.settings - - row = layout.row() - row.template_list("TEXTURE_UL_texslots", "", part, "texture_slots", part, "active_texture_index", rows=2) - - col = row.column(align=True) - col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP' - col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN' - col.menu("TEXTURE_MT_specials", icon='DOWNARROW_HLT', text="") - - if not part.active_texture: - layout.template_ID(part, "active_texture", new="texture.new") - else: - slot = part.texture_slots[part.active_texture_index] - layout.template_ID(slot, "texture", new="texture.new") - - class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel): bl_label = "Bake" bl_context = "render" @@ -1533,69 +1273,80 @@ class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True scene = context.scene cscene = scene.cycles cbk = scene.render.bake - - layout.operator("object.bake", icon='RENDER_STILL').type = cscene.bake_type - - col = layout.column() - col.prop(cscene, "bake_type") + rd = scene.render col = layout.column() + col.prop(rd, "use_bake_multires") + if rd.use_bake_multires: + col.prop(rd, "bake_type") - if cscene.bake_type == 'NORMAL': - col.prop(cbk, "normal_space", text="Space") + col = layout.column() + col.prop(rd, "bake_margin") + col.prop(rd, "use_bake_clear") - row = col.row(align=True) - row.label(text="Swizzle:") - row.prop(cbk, "normal_r", text="") - row.prop(cbk, "normal_g", text="") - row.prop(cbk, "normal_b", text="") + if rd.bake_type == 'DISPLACEMENT': + col.prop(rd, "use_bake_lores_mesh") - elif cscene.bake_type == 'COMBINED': - row = col.row(align=True) - row.prop(cbk, "use_pass_direct", toggle=True) - row.prop(cbk, "use_pass_indirect", toggle=True) + col.operator("object.bake_image", icon='RENDER_STILL') - split = col.split() - split.active = cbk.use_pass_direct or cbk.use_pass_indirect - - col = split.column() - col.prop(cbk, "use_pass_diffuse") - col.prop(cbk, "use_pass_glossy") - col.prop(cbk, "use_pass_transmission") - - col = split.column() - col.prop(cbk, "use_pass_subsurface") - col.prop(cbk, "use_pass_ambient_occlusion") - col.prop(cbk, "use_pass_emit") + else: + col.prop(cscene, "bake_type") + + col = layout.column() + + if cscene.bake_type == 'NORMAL': + col.prop(cbk, "normal_space", text="Space") + + sub = col.row(align=True) + sub.prop(cbk, "normal_r", text="Swizzle R") + sub.prop(cbk, "normal_g", text="G") + sub.prop(cbk, "normal_b", text="B") + + elif cscene.bake_type == 'COMBINED': + row = col.row(align=True) + row.use_property_split = False + row.prop(cbk, "use_pass_direct", toggle=True) + row.prop(cbk, "use_pass_indirect", toggle=True) + + col = col.column() + col.active = cbk.use_pass_direct or cbk.use_pass_indirect + col.prop(cbk, "use_pass_diffuse") + col.prop(cbk, "use_pass_glossy") + col.prop(cbk, "use_pass_transmission") + col.prop(cbk, "use_pass_subsurface") + col.prop(cbk, "use_pass_ambient_occlusion") + col.prop(cbk, "use_pass_emit") + + elif cscene.bake_type in {'DIFFUSE', 'GLOSSY', 'TRANSMISSION', 'SUBSURFACE'}: + row = col.row(align=True) + row.prop(cbk, "use_pass_direct", toggle=True) + row.prop(cbk, "use_pass_indirect", toggle=True) + row.prop(cbk, "use_pass_color", toggle=True) - elif cscene.bake_type in {'DIFFUSE', 'GLOSSY', 'TRANSMISSION', 'SUBSURFACE'}: - row = col.row(align=True) - row.prop(cbk, "use_pass_direct", toggle=True) - row.prop(cbk, "use_pass_indirect", toggle=True) - row.prop(cbk, "use_pass_color", toggle=True) + layout.separator() - layout.separator() + col = layout.column() + col.prop(cbk, "margin") + col.prop(cbk, "use_clear", text="Clear Image") - split = layout.split() + col.separator() - col = split.column() - col.prop(cbk, "margin") - col.prop(cbk, "use_clear") + col.prop(cbk, "use_selected_to_active") + sub = col.column() + sub.active = cbk.use_selected_to_active + sub.prop(cbk, "use_cage", text="Cage") + if cbk.use_cage: + sub.prop(cbk, "cage_extrusion", text="Extrusion") + sub.prop_search(cbk, "cage_object", scene, "objects", text="") + else: + sub.prop(cbk, "cage_extrusion", text="Ray Distance") - col = split.column() - col.prop(cbk, "use_selected_to_active") - sub = col.column() - sub.active = cbk.use_selected_to_active - sub.prop(cbk, "use_cage", text="Cage") - if cbk.use_cage: - sub.prop(cbk, "cage_extrusion", text="Extrusion") - sub.prop_search(cbk, "cage_object", scene, "objects", text="") - else: - sub.prop(cbk, "cage_extrusion", text="Ray Distance") + layout.operator("object.bake", icon='RENDER_STILL').type = cscene.bake_type class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel): @@ -1649,37 +1400,6 @@ class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel): col.prop(cscene, "debug_bvh_type") -class CYCLES_PARTICLE_PT_curve_settings(CyclesButtonsPanel, Panel): - bl_label = "Cycles Hair Settings" - bl_context = "particle" - - @classmethod - def poll(cls, context): - scene = context.scene - ccscene = scene.cycles_curves - psys = context.particle_system - use_curves = ccscene.use_curves and psys - return CyclesButtonsPanel.poll(context) and use_curves and psys.settings.type == 'HAIR' - - def draw(self, context): - layout = self.layout - - psys = context.particle_settings - cpsys = psys.cycles - - row = layout.row() - row.prop(cpsys, "shape", text="Shape") - - layout.label(text="Thickness:") - row = layout.row() - row.prop(cpsys, "root_width", text="Root") - row.prop(cpsys, "tip_width", text="Tip") - - row = layout.row() - row.prop(cpsys, "radius_scale", text="Scaling") - row.prop(cpsys, "use_closetip", text="Close tip") - - class CYCLES_SCENE_PT_simplify(CyclesButtonsPanel, Panel): bl_label = "Simplify" bl_context = "scene" @@ -1739,38 +1459,30 @@ class CYCLES_SCENE_PT_simplify(CyclesButtonsPanel, Panel): col = split.column() col.prop(cscene, "ao_bounces_render") + def draw_device(self, context): scene = context.scene layout = self.layout + layout.use_property_split = True - if scene.render.engine == 'CYCLES': + if context.engine == 'CYCLES': from . import engine cscene = scene.cycles - layout.prop(cscene, "feature_set") - - split = layout.split(percentage=1 / 3) - split.label("Device:") - row = split.row() - row.active = show_device_active(context) - row.prop(cscene, "device", text="") - - if engine.with_osl() and use_cpu(context): - layout.prop(cscene, "shading_system") + col = layout.column() + col.prop(cscene, "feature_set") def draw_pause(self, context): layout = self.layout scene = context.scene - if scene.render.engine == "CYCLES": + if context.engine == "CYCLES": view = context.space_data - if view.viewport_shade == 'RENDERED': + if view.shading.type == 'RENDERED': cscene = scene.cycles - layername = scene.render.layers.active.name layout.prop(cscene, "preview_pause", icon="PAUSE", text="") - layout.prop(cscene, "preview_active_layer", icon="RENDERLAYERS", text=layername) def get_panels(): @@ -1780,48 +1492,14 @@ def get_panels(): 'DATA_PT_falloff_curve', 'DATA_PT_lamp', 'DATA_PT_preview', - 'DATA_PT_shadow', 'DATA_PT_spot', - 'DATA_PT_sunsky', 'MATERIAL_PT_context_material', - 'MATERIAL_PT_diffuse', - 'MATERIAL_PT_flare', - 'MATERIAL_PT_halo', - 'MATERIAL_PT_mirror', - 'MATERIAL_PT_options', - 'MATERIAL_PT_pipeline', 'MATERIAL_PT_preview', - 'MATERIAL_PT_shading', - 'MATERIAL_PT_shadow', - 'MATERIAL_PT_specular', - 'MATERIAL_PT_sss', - 'MATERIAL_PT_strand', - 'MATERIAL_PT_transp', - 'MATERIAL_PT_volume_density', - 'MATERIAL_PT_volume_integration', - 'MATERIAL_PT_volume_lighting', - 'MATERIAL_PT_volume_options', - 'MATERIAL_PT_volume_shading', - 'MATERIAL_PT_volume_transp', - 'RENDERLAYER_PT_layer_options', - 'RENDERLAYER_PT_layer_passes', - 'RENDERLAYER_PT_views', - 'RENDER_PT_antialiasing', - 'RENDER_PT_bake', - 'RENDER_PT_motion_blur', - 'RENDER_PT_performance', + 'VIEWLAYER_PT_filter', + 'VIEWLAYER_PT_layer_passes', 'RENDER_PT_post_processing', - 'RENDER_PT_shading', 'SCENE_PT_simplify', - 'TEXTURE_PT_context_texture', - 'WORLD_PT_ambient_occlusion', - 'WORLD_PT_environment_lighting', - 'WORLD_PT_gather', - 'WORLD_PT_indirect_lighting', - 'WORLD_PT_mist', - 'WORLD_PT_preview', - 'WORLD_PT_world' - } + } panels = [] for panel in bpy.types.Panel.__subclasses__(): @@ -1841,9 +1519,8 @@ classes = ( CYCLES_RENDER_PT_motion_blur, CYCLES_RENDER_PT_film, CYCLES_RENDER_PT_performance, - CYCLES_RENDER_PT_layer_options, + CYCLES_RENDER_PT_filter, CYCLES_RENDER_PT_layer_passes, - CYCLES_RENDER_PT_views, CYCLES_RENDER_PT_denoising, CYCLES_PT_post_processing, CYCLES_CAMERA_PT_dof, @@ -1867,15 +1544,8 @@ classes = ( CYCLES_MATERIAL_PT_volume, CYCLES_MATERIAL_PT_displacement, CYCLES_MATERIAL_PT_settings, - CYCLES_MATERIAL_PT_viewport, - CYCLES_TEXTURE_PT_context, - CYCLES_TEXTURE_PT_node, - CYCLES_TEXTURE_PT_mapping, - CYCLES_TEXTURE_PT_colors, - CYCLES_PARTICLE_PT_textures, CYCLES_RENDER_PT_bake, CYCLES_RENDER_PT_debug, - CYCLES_PARTICLE_PT_curve_settings, CYCLES_SCENE_PT_simplify, ) @@ -1883,7 +1553,7 @@ classes = ( def register(): from bpy.utils import register_class - bpy.types.RENDER_PT_render.append(draw_device) + bpy.types.RENDER_PT_context.append(draw_device) bpy.types.VIEW3D_HT_header.append(draw_pause) for panel in get_panels(): @@ -1896,7 +1566,7 @@ def register(): def unregister(): from bpy.utils import unregister_class - bpy.types.RENDER_PT_render.remove(draw_device) + bpy.types.RENDER_PT_context.remove(draw_device) bpy.types.VIEW3D_HT_header.remove(draw_pause) for panel in get_panels(): |