diff options
Diffstat (limited to 'intern/cycles/blender/addon/ui.py')
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 1482 |
1 files changed, 737 insertions, 745 deletions
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 2b11a2eefb0..33e60580e37 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -17,28 +17,30 @@ # <pep8 compliant> import bpy +from bpy_extras.node_utils import find_node_input, find_output_node +from bl_operators.presets import PresetMenu from bpy.types import ( - Panel, - Menu, - Operator, - ) + Panel, + Menu, + Operator, +) -class CYCLES_MT_sampling_presets(Menu): +class CYCLES_MT_sampling_presets(PresetMenu): bl_label = "Sampling Presets" preset_subdir = "cycles/sampling" preset_operator = "script.execute_preset" + preset_add_operator = "render.cycles_sampling_preset_add" COMPAT_ENGINES = {'CYCLES'} - draw = Menu.draw_preset -class CYCLES_MT_integrator_presets(Menu): +class CYCLES_MT_integrator_presets(PresetMenu): bl_label = "Integrator Presets" preset_subdir = "cycles/integrator" preset_operator = "script.execute_preset" + preset_add_operator = "render.cycles_integrator_preset_add" COMPAT_ENGINES = {'CYCLES'} - draw = Menu.draw_preset class CyclesButtonsPanel: @@ -49,8 +51,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 +87,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': @@ -143,73 +145,77 @@ class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel): bl_label = "Sampling" bl_options = {'DEFAULT_CLOSED'} + def draw_header_preset(self, context): + CYCLES_MT_sampling_presets.draw_panel_header(self.layout) + def draw(self, context): layout = self.layout + layout.use_property_split = False scene = context.scene cscene = scene.cycles - row = layout.row(align=True) - row.menu("CYCLES_MT_sampling_presets", text=bpy.types.CYCLES_MT_sampling_presets.bl_label) - row.operator("render.cycles_sampling_preset_add", text="", icon="ZOOMIN") - row.operator("render.cycles_sampling_preset_add", text="", icon="ZOOMOUT").remove_active = True + layout.use_property_split = 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:") - - 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") + col.prop(cscene, "preview_samples", text="Viewport") + col.separator() + 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 = 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") - subsub = sub.row(align=True) - subsub.active = use_sample_all_lights(context) - subsub.prop(cscene, "mesh_light_samples", text="Mesh Light") + col = layout.column(align=True) + col.label(text="AA Samples") + col.prop(cscene, "aa_samples", text="Render") + col.prop(cscene, "preview_aa_samples", text="Preview") - sub.prop(cscene, "subsurface_samples", text="Subsurface") - sub.prop(cscene, "volume_samples", text="Volume") + col = layout.column(align=True) + col.label(text="Samples") + col.prop(cscene, "diffuse_samples", text="Diffuse") + col.prop(cscene, "glossy_samples", text="Glossy") + col.prop(cscene, "transmission_samples", text="Transmission") + col.prop(cscene, "ao_samples", text="AO") + + sub = col.row(align=True) + sub.active = use_sample_all_lights(context) + sub.prop(cscene, "mesh_light_samples", text="Mesh Light") + col.prop(cscene, "subsurface_samples", text="Subsurface") + col.prop(cscene, "volume_samples", text="Volume") + col.separator() + 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") + row = layout.row(align=True) + row.prop(cscene, "seed") + row.prop(cscene, "use_animated_seed", text="", icon='TIME') + + layout.prop(cscene, "sampling_pattern", text="Pattern") + + +class CYCLES_RENDER_PT_sampling_light(CyclesButtonsPanel, Panel): + bl_label = "Light" + bl_parent_id = "CYCLES_RENDER_PT_sampling" + bl_options = {'DEFAULT_CLOSED'} - for rl in scene.render.layers: - if rl.samples > 0: - layout.separator() - layout.row().prop(cscene, "use_layer_samples") - break + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + cscene = scene.cycles + + 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") draw_samples_info(layout, context) @@ -219,98 +225,140 @@ class CYCLES_RENDER_PT_geometry(CyclesButtonsPanel, Panel): bl_options = {'DEFAULT_CLOSED'} def draw(self, context): + pass + + +class CYCLES_RENDER_PT_geometry_subdivision(CyclesButtonsPanel, Panel): + bl_label = "Subdivision" + bl_parent_id = "CYCLES_RENDER_PT_geometry" + + @classmethod + def poll(self, context): + return context.scene.cycles.feature_set == 'EXPERIMENTAL' + + 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() + sub = col.column(align=True) + sub.prop(cscene, "dicing_rate", text="Dicing Rate Render") + sub.prop(cscene, "preview_dicing_rate", text="Preview") - layout.separator() + col.separator() - if cscene.feature_set == 'EXPERIMENTAL': - layout.label("Subdivision Rate:") - split = layout.split() + col.prop(cscene, "offscreen_dicing_scale", text="Offscreen Scale") + col.prop(cscene, "max_subdivisions") - col = split.column() - sub = col.column(align=True) - sub.prop(cscene, "dicing_rate", text="Render") - sub.prop(cscene, "preview_dicing_rate", text="Preview") + col.prop(cscene, "dicing_camera") - col = split.column() - col.prop(cscene, "offscreen_dicing_scale", text="Offscreen Scale") - col.prop(cscene, "max_subdivisions") - layout.prop(cscene, "dicing_camera") +class CYCLES_RENDER_PT_geometry_volume(CyclesButtonsPanel, Panel): + bl_label = "Volume" + bl_parent_id = "CYCLES_RENDER_PT_geometry" - layout.separator() + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + cscene = scene.cycles + ccscene = scene.cycles_curves - layout.label("Hair:") - layout.prop(ccscene, "use_curves", text="Use Hair") col = layout.column() - col.active = ccscene.use_curves + col.prop(cscene, "volume_step_size", text="Step Size") + col.prop(cscene, "volume_max_steps", text="Max Steps") - col.prop(ccscene, "primitive", text="Primitive") - col.prop(ccscene, "shape", text="Shape") +class CYCLES_RENDER_PT_geometry_hair(CyclesButtonsPanel, Panel): + bl_label = "Hair" + bl_parent_id = "CYCLES_RENDER_PT_geometry" + bl_options = {'DEFAULT_CLOSED'} + + def draw_header(self, context): + layout = self.layout + scene = context.scene + cscene = scene.cycles + ccscene = scene.cycles_curves + + layout.prop(ccscene, "use_curves", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + cscene = scene.cycles + ccscene = scene.cycles_curves + + layout.active = ccscene.use_curves + + col = layout.column() + 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" bl_options = {'DEFAULT_CLOSED'} + def draw_header_preset(self, context): + CYCLES_MT_integrator_presets.draw_panel_header(self.layout) + + def draw(self, context): + pass + + +class CYCLES_RENDER_PT_light_paths_max_bounces(CyclesButtonsPanel, Panel): + bl_label = "Max Bounces" + bl_parent_id = "CYCLES_RENDER_PT_light_paths" + def draw(self, context): layout = self.layout + layout.use_property_split = True scene = context.scene cscene = scene.cycles - row = layout.row(align=True) - row.menu("CYCLES_MT_integrator_presets", text=bpy.types.CYCLES_MT_integrator_presets.bl_label) - row.operator("render.cycles_integrator_preset_add", text="", icon="ZOOMIN") - row.operator("render.cycles_integrator_preset_add", text="", icon="ZOOMOUT").remove_active = True + col = layout.column(align=True) + col.prop(cscene, "max_bounces", text="Total") - split = layout.split() + col = layout.column(align=True) + col.prop(cscene, "diffuse_bounces", text="Diffuse") + col.prop(cscene, "glossy_bounces", text="Glossy") + col.prop(cscene, "transparent_max_bounces", text="Transparency") + col.prop(cscene, "transmission_bounces", text="Transmission") + col.prop(cscene, "volume_bounces", text="Volume") - col = split.column() - sub = col.column(align=True) - sub.label("Transparency:") - sub.prop(cscene, "transparent_max_bounces", text="Max") +class CYCLES_RENDER_PT_light_paths_caustics(CyclesButtonsPanel, Panel): + bl_label = "Caustics" + bl_parent_id = "CYCLES_RENDER_PT_light_paths" + bl_options = {'DEFAULT_CLOSED'} - col.separator() + def draw(self, context): + layout = self.layout + layout.use_property_split = True + scene = context.scene + cscene = scene.cycles + + 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 +372,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 @@ -333,9 +382,29 @@ class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel): col = layout.column() col.prop(cscene, "motion_blur_position", text="Position") col.prop(rd, "motion_blur_shutter") + col.separator() + col.prop(cscene, "rolling_shutter_type", text="Rolling Shutter") + sub = col.column() + sub.active = cscene.rolling_shutter_type != 'NONE' + sub.prop(cscene, "rolling_shutter_duration") + + +class CYCLES_RENDER_PT_motion_blur_curve(CyclesButtonsPanel, Panel): + bl_label = "Shutter Curve" + bl_parent_id = "CYCLES_RENDER_PT_motion_blur" + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + cscene = scene.cycles + rd = scene.render + layout.active = rd.use_motion_blur col = layout.column() - col.label("Shutter curve:") + col.template_curve_mapping(rd, "motion_blur_shutter_curve") col = layout.column(align=True) @@ -347,40 +416,65 @@ class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel): row.operator("render.shutter_curve_preset", icon='LINCURVE', text="").shape = 'LINE' row.operator("render.shutter_curve_preset", icon='NOCURVE', text="").shape = 'MAX' - col = layout.column() - col.prop(cscene, "rolling_shutter_type") - row = col.row() - row.active = cscene.rolling_shutter_type != 'NONE' - row.prop(cscene, "rolling_shutter_duration") - 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 + + col = layout.column() + col.prop(cscene, "film_exposure") + + +class CYCLES_RENDER_PT_film_transparency(CyclesButtonsPanel, Panel): + bl_label = "Transparency" + bl_parent_id = "CYCLES_RENDER_PT_film" + + def draw_header(self, context): + layout = self.layout + rd = context.scene.render scene = context.scene cscene = scene.cycles - split = layout.split() + layout.prop(cscene, "film_transparent", text="") - col = split.column() - col.prop(cscene, "film_exposure") - col.separator() - sub = col.column(align=True) - sub.prop(cscene, "pixel_filter_type", text="") - if cscene.pixel_filter_type != 'BOX': - sub.prop(cscene, "filter_width", text="Width") + def draw(self, context): + layout = self.layout + layout.use_property_split = True + scene = context.scene + cscene = scene.cycles - col = split.column() - col.prop(cscene, "film_transparent") - sub = col.row() - 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") + layout.active = cscene.film_transparent + + col = layout.column() + col.prop(cscene, "film_transparent_glass", text="Transparent Glass") + + sub = col.column() sub.active = cscene.film_transparent and cscene.film_transparent_glass + sub.prop(cscene, "film_transparent_roughness", text="Roughness Threshold") + + +class CYCLES_RENDER_PT_film_pixel_filter(CyclesButtonsPanel, Panel): + bl_label = "Pixel Filter" + bl_parent_id = "CYCLES_RENDER_PT_film" + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + scene = context.scene + cscene = scene.cycles + + col = layout.column() + col.prop(cscene, "pixel_filter_type", text="Type") + if cscene.pixel_filter_type != 'BOX': + col.prop(cscene, "filter_width", text="Width") class CYCLES_RENDER_PT_performance(CyclesButtonsPanel, Panel): @@ -389,104 +483,153 @@ 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.active = show_device_active(context) + col.prop(cscene, "device") - col = split.column(align=True) + from . import engine + if engine.with_osl() and use_cpu(context): + col.prop(cscene, "shading_system") + + +class CYCLES_RENDER_PT_performance_threads(CyclesButtonsPanel, Panel): + bl_label = "Threads" + bl_parent_id = "CYCLES_RENDER_PT_performance" + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + rd = scene.render + cscene = scene.cycles + + col = layout.column() - col.label(text="Threads:") - col.row(align=True).prop(rd, "threads_mode", expand=True) + col.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="") +class CYCLES_RENDER_PT_performance_tiles(CyclesButtonsPanel, Panel): + bl_label = "Tiles" + bl_parent_id = "CYCLES_RENDER_PT_performance" + + def draw(self, context): + layout = self.layout + layout.use_property_split = True - sub.prop(rd, "tile_x", text="X") + scene = context.scene + rd = scene.render + cscene = scene.cycles + + col = layout.column() + + 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() - col.label(text="Final Render:") - col.prop(rd, "use_save_buffers") - col.prop(rd, "use_persistent_data", text="Persistent Images") +class CYCLES_RENDER_PT_performance_acceleration_structure(CyclesButtonsPanel, Panel): + bl_label = "Acceleration Structure" + bl_parent_id = "CYCLES_RENDER_PT_performance" + bl_options = {'DEFAULT_CLOSED'} - col.separator() + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + rd = scene.render + cscene = scene.cycles + + col = layout.column() - col.label(text="Acceleration structure:") col.prop(cscene, "debug_use_spatial_splits") col.prop(cscene, "debug_use_hair_bvh") + sub = col.column() + sub.active = not cscene.debug_use_spatial_splits + sub.prop(cscene, "debug_bvh_time_steps") - row = col.row() - row.active = not cscene.debug_use_spatial_splits - row.prop(cscene, "debug_bvh_time_steps") + +class CYCLES_RENDER_PT_performance_final_render(CyclesButtonsPanel, Panel): + bl_label = "Final Render" + bl_parent_id = "CYCLES_RENDER_PT_performance" + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + rd = scene.render + cscene = scene.cycles 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, "use_save_buffers") + col.prop(rd, "use_persistent_data", text="Persistent Images") -class CYCLES_RENDER_PT_layer_options(CyclesButtonsPanel, Panel): - bl_label = "Layer" - bl_context = "render_layer" +class CYCLES_RENDER_PT_performance_viewport(CyclesButtonsPanel, Panel): + bl_label = "Viewport" + bl_parent_id = "CYCLES_RENDER_PT_performance" + bl_options = {'DEFAULT_CLOSED'} def draw(self, context): layout = self.layout - with_freestyle = bpy.app.build_options.freestyle + layout.use_property_split = True scene = context.scene rd = scene.render - rl = rd.layers.active + cscene = scene.cycles - split = layout.split() + col = layout.column() + col.prop(rd, "preview_pixel_size", text="Pixel Size") + col.prop(cscene, "preview_start_resolution", text="Start Pixels") - 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") +class CYCLES_RENDER_PT_filter(CyclesButtonsPanel, Panel): + bl_label = "Filter" + bl_context = "view_layer" - split = layout.split() + def draw(self, context): + layout = self.layout + with_freestyle = bpy.app.build_options.freestyle - col = split.column() - col.label(text="Material:") - col.prop(rl, "material_override", text="") - col.separator() - col.prop(rl, "samples") + scene = context.scene + rd = scene.render + view_layer = context.view_layer - 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 +639,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 +799,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): @@ -699,6 +820,7 @@ class CYCLES_CAMERA_PT_dof(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True cam = context.camera ccam = cam.cycles @@ -707,16 +829,62 @@ class CYCLES_CAMERA_PT_dof(CyclesButtonsPanel, Panel): split = layout.split() col = split.column() - col.label("Focus:") - col.prop(cam, "dof_object", text="") + col.prop(cam, "dof_object", text="Focus Object") sub = col.row() sub.active = cam.dof_object is None sub.prop(cam, "dof_distance", text="Distance") + +class CYCLES_CAMERA_PT_dof_aperture(CyclesButtonsPanel, Panel): + bl_label = "Aperture" + bl_parent_id = "CYCLES_CAMERA_PT_dof" + + @classmethod + def poll(cls, context): + return context.camera and CyclesButtonsPanel.poll(context) + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, num_columns=0, even_columns=True, even_rows=False, align=False) + + cam = context.camera + ccam = cam.cycles + dof_options = cam.gpu_dof + + col = flow.column() + col.prop(ccam, "aperture_type") + if ccam.aperture_type == 'RADIUS': + col.prop(ccam, "aperture_size", text="Size") + elif ccam.aperture_type == 'FSTOP': + col.prop(ccam, "aperture_fstop", text="Number") + col.separator() + + col = flow.column() + col.prop(ccam, "aperture_blades", text="Blades") + col.prop(ccam, "aperture_rotation", text="Rotation") + col.prop(ccam, "aperture_ratio", text="Ratio") + + +class CYCLES_CAMERA_PT_dof_viewport(CyclesButtonsPanel, Panel): + bl_label = "Viewport" + bl_parent_id = "CYCLES_CAMERA_PT_dof" + + @classmethod + def poll(cls, context): + return context.camera and CyclesButtonsPanel.poll(context) + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, num_columns=0, even_columns=True, even_rows=False, align=False) + + cam = context.camera + dof_options = cam.gpu_dof + hq_support = dof_options.is_hq_supported - sub = col.column(align=True) - sub.label("Viewport:") + sub = flow.column(align=True) subhq = sub.column() subhq.active = hq_support subhq.prop(dof_options, "use_high_quality") @@ -724,21 +892,6 @@ class CYCLES_CAMERA_PT_dof(CyclesButtonsPanel, Panel): if dof_options.use_high_quality and hq_support: sub.prop(dof_options, "blades") - col = split.column() - - col.label("Aperture:") - sub = col.column(align=True) - sub.prop(ccam, "aperture_type", text="") - if ccam.aperture_type == 'RADIUS': - sub.prop(ccam, "aperture_size", text="Size") - elif ccam.aperture_type == 'FSTOP': - sub.prop(ccam, "aperture_fstop", text="Number") - - sub = col.column(align=True) - sub.prop(ccam, "aperture_blades", text="Blades") - sub.prop(ccam, "aperture_rotation", text="Rotation") - sub.prop(ccam, "aperture_ratio", text="Ratio") - class CYCLES_PT_context_material(CyclesButtonsPanel, Panel): bl_label = "" @@ -811,7 +964,7 @@ class CYCLES_OBJECT_PT_motion_blur(CyclesButtonsPanel, Panel): if CyclesButtonsPanel.poll(context) and ob: if ob.type in {'MESH', 'CURVE', 'CURVE', 'SURFACE', 'FONT', 'META', 'CAMERA'}: return True - if ob.dupli_type == 'GROUP' and ob.dupli_group: + if ob.dupli_type == 'COLLECTION' and ob.dupli_group: return True # TODO(sergey): More duplicator types here? return False @@ -856,7 +1009,7 @@ class CYCLES_OBJECT_PT_cycles_settings(CyclesButtonsPanel, Panel): ob = context.object return (CyclesButtonsPanel.poll(context) and ob and ((ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'LAMP'}) or - (ob.dupli_type == 'GROUP' and ob.dupli_group))) + (ob.dupli_type == 'COLLECTION' and ob.dupli_group))) def draw(self, context): layout = self.layout @@ -916,43 +1069,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 +1096,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 +1135,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 +1171,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 +1232,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,12 +1250,13 @@ 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): bl_label = "Ambient Occlusion" bl_context = "world" + bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): @@ -1131,15 +1268,16 @@ class CYCLES_WORLD_PT_ambient_occlusion(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True light = context.world.light_settings scene = context.scene - row = layout.row() - sub = row.row() + col = layout.column() + sub = col.column() sub.active = light.use_ambient_occlusion or scene.render.use_simplify sub.prop(light, "ao_factor", text="Factor") - row.prop(light, "distance", text="Distance") + col.prop(light, "distance", text="Distance") class CYCLES_WORLD_PT_mist(CyclesButtonsPanel, Panel): @@ -1151,8 +1289,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 @@ -1204,35 +1342,67 @@ class CYCLES_WORLD_PT_settings(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True world = context.world cworld = world.cycles # cscene = context.scene.cycles - split = layout.split() + col = layout.column() - col = split.column() +class CYCLES_WORLD_PT_settings_surface(CyclesButtonsPanel, Panel): + bl_label = "Surface" + bl_parent_id = "CYCLES_WORLD_PT_settings" + bl_context = "world" + + @classmethod + def poll(cls, context): + return context.world and CyclesButtonsPanel.poll(context) + + def draw(self, context): + layout = self.layout + layout.use_property_split = True - col.label(text="Surface:") + world = context.world + cworld = world.cycles + + col = layout.column() col.prop(cworld, "sampling_method", text="Sampling") - sub = col.column(align=True) + sub = col.column() sub.active = cworld.sampling_method != 'NONE' subsub = sub.row(align=True) subsub.active = cworld.sampling_method == 'MANUAL' subsub.prop(cworld, "sample_map_resolution") if use_branched_path(context): - subsub = sub.row(align=True) + subsub = sub.column(align=True) subsub.active = use_sample_all_lights(context) subsub.prop(cworld, "samples") sub.prop(cworld, "max_bounces") - col = split.column() - col.label(text="Volume:") + +class CYCLES_WORLD_PT_settings_volume(CyclesButtonsPanel, Panel): + bl_label = "Volume" + bl_parent_id = "CYCLES_WORLD_PT_settings" + bl_context = "world" + + @classmethod + def poll(cls, context): + return context.world and CyclesButtonsPanel.poll(context) + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + world = context.world + cworld = world.cycles + + col = layout.column() + sub = col.column() sub.active = use_cpu(context) - sub.prop(cworld, "volume_sampling", text="") - col.prop(cworld, "volume_interpolation", text="") + sub.prop(cworld, "volume_sampling", text="Sampling") + col.prop(cworld, "volume_interpolation", text="Interpolation") col.prop(cworld, "homogeneous_volume", text="Homogeneous") @@ -1261,7 +1431,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") @@ -1281,7 +1451,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): @@ -1297,7 +1467,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): @@ -1310,221 +1480,60 @@ class CYCLES_MATERIAL_PT_settings(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True mat = context.material cmat = mat.cycles - split = layout.split() - col = split.column() - col.label(text="Surface:") - col.prop(cmat, "sample_as_light", text="Multiple Importance") - col.prop(cmat, "use_transparent_shadow") - - col.separator() - col.label(text="Geometry:") - col.prop(cmat, "displacement_method", text="") - - col = split.column() - col.label(text="Volume:") - sub = col.column() - sub.active = use_cpu(context) - sub.prop(cmat, "volume_sampling", text="") - col.prop(cmat, "volume_interpolation", text="") - col.prop(cmat, "homogeneous_volume", text="Homogeneous") - - col.separator() - col.prop(mat, "pass_index") + layout.prop(mat, "pass_index") -class CYCLES_MATERIAL_PT_viewport(CyclesButtonsPanel, Panel): - bl_label = "Viewport" +class CYCLES_MATERIAL_PT_settings_surface(CyclesButtonsPanel, Panel): + bl_label = "Surface" + bl_parent_id = "CYCLES_MATERIAL_PT_settings" 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 + layout.use_property_split = True - 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() + mat = context.material + cmat = mat.cycles - layout.prop(mapping, "use_color_ramp", text="Ramp") - if mapping.use_color_ramp: - layout.template_color_ramp(mapping, "color_ramp", expand=True) + col = layout.column() + col.prop(cmat, "sample_as_light", text="Multiple Importance") + col.prop(cmat, "use_transparent_shadow") + col.prop(cmat, "displacement_method", text="Displacement Method") -class CYCLES_PARTICLE_PT_textures(CyclesButtonsPanel, Panel): - bl_label = "Textures" - bl_context = "particle" - bl_options = {'DEFAULT_CLOSED'} +class CYCLES_MATERIAL_PT_settings_volume(CyclesButtonsPanel, Panel): + bl_label = "Volume" + bl_parent_id = "CYCLES_MATERIAL_PT_settings" + bl_context = "material" @classmethod def poll(cls, context): - psys = context.particle_system - return psys and CyclesButtonsPanel.poll(context) + return context.material and CyclesButtonsPanel.poll(context) def draw(self, context): layout = self.layout + layout.use_property_split = True - psys = context.particle_system - part = psys.settings + mat = context.material + cmat = mat.cycles - row = layout.row() - row.template_list("TEXTURE_UL_texslots", "", part, "texture_slots", part, "active_texture_index", rows=2) + col = layout.column() + sub = col.column() + sub.active = use_cpu(context) + sub.prop(cmat, "volume_sampling", text="Sampling") + col.prop(cmat, "volume_interpolation", text="Interpolation") + col.prop(cmat, "homogeneous_volume", text="Homogeneous") - 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): @@ -1535,69 +1544,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") - - 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="") + col = layout.column() + col.prop(rd, "bake_margin") + col.prop(rd, "use_bake_clear") - 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) + if rd.bake_type == 'DISPLACEMENT': + col.prop(rd, "use_bake_lores_mesh") - split = col.split() - split.active = cbk.use_pass_direct or cbk.use_pass_indirect + col.operator("object.bake_image", icon='RENDER_STILL') - col = split.column() - col.prop(cbk, "use_pass_diffuse") - col.prop(cbk, "use_pass_glossy") - col.prop(cbk, "use_pass_transmission") + 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) - col = split.column() - col.prop(cbk, "use_pass_subsurface") - col.prop(cbk, "use_pass_ambient_occlusion") - col.prop(cbk, "use_pass_emit") + layout.separator() - 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) + col = layout.column() + col.prop(cbk, "margin") + col.prop(cbk, "use_clear", text="Clear Image") - layout.separator() - - 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): @@ -1651,48 +1671,51 @@ 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" +class CYCLES_SCENE_PT_simplify(CyclesButtonsPanel, Panel): + bl_label = "Simplify" + bl_context = "scene" + COMPAT_ENGINES = {'CYCLES'} - @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_header(self, context): + rd = context.scene.render + self.layout.prop(rd, "use_simplify", text="") def draw(self, context): - layout = self.layout + pass - psys = context.particle_settings - cpsys = psys.cycles - row = layout.row() - row.prop(cpsys, "shape", text="Shape") +class CYCLES_SCENE_PT_simplify_viewport(CyclesButtonsPanel, Panel): + bl_label = "Viewport" + bl_context = "scene" + bl_parent_id = "CYCLES_SCENE_PT_simplify" + COMPAT_ENGINES = {'CYCLES'} - layout.label(text="Thickness:") - row = layout.row() - row.prop(cpsys, "root_width", text="Root") - row.prop(cpsys, "tip_width", text="Tip") + def draw(self, context): + layout = self.layout + layout.use_property_split = True - row = layout.row() - row.prop(cpsys, "radius_scale", text="Scaling") - row.prop(cpsys, "use_closetip", text="Close tip") + scene = context.scene + rd = scene.render + cscene = scene.cycles + layout.active = rd.use_simplify -class CYCLES_SCENE_PT_simplify(CyclesButtonsPanel, Panel): - bl_label = "Simplify" + col = layout.column() + col.prop(rd, "simplify_subdivision", text="Max Subdivision") + col.prop(rd, "simplify_child_particles", text="Child Particles") + col.prop(cscene, "texture_limit", text="Texture Limit") + col.prop(cscene, "ao_bounces", text="AO Bounces") + + +class CYCLES_SCENE_PT_simplify_render(CyclesButtonsPanel, Panel): + bl_label = "Render" bl_context = "scene" + bl_parent_id = "CYCLES_SCENE_PT_simplify" COMPAT_ENGINES = {'CYCLES'} - def draw_header(self, context): - rd = context.scene.render - self.layout.prop(rd, "use_simplify", text="") - def draw(self, context): layout = self.layout + layout.use_property_split = True scene = context.scene rd = scene.render @@ -1700,79 +1723,67 @@ class CYCLES_SCENE_PT_simplify(CyclesButtonsPanel, Panel): layout.active = rd.use_simplify - col = layout.column(align=True) - col.label(text="Subdivision") - row = col.row(align=True) - row.prop(rd, "simplify_subdivision", text="Viewport") - row.prop(rd, "simplify_subdivision_render", text="Render") + col = layout.column() - col = layout.column(align=True) - col.label(text="Child Particles") - row = col.row(align=True) - row.prop(rd, "simplify_child_particles", text="Viewport") - row.prop(rd, "simplify_child_particles_render", text="Render") + col.prop(rd, "simplify_subdivision_render", text="Max Subdivision") + col.prop(rd, "simplify_child_particles_render", text="Child Particles") + col.prop(cscene, "texture_limit_render", text="Texture Limit") + col.prop(cscene, "ao_bounces_render", text="AO Bounces") - col = layout.column(align=True) - split = col.split() - sub = split.column() - sub.label(text="Texture Limit Viewport") - sub.prop(cscene, "texture_limit", text="") - sub = split.column() - sub.label(text="Texture Limit Render") - sub.prop(cscene, "texture_limit_render", text="") - split = layout.split() - col = split.column() +class CYCLES_SCENE_PT_simplify_culling(CyclesButtonsPanel, Panel): + bl_label = "Culling" + bl_context = "scene" + bl_parent_id = "CYCLES_SCENE_PT_simplify" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'CYCLES'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + rd = scene.render + cscene = scene.cycles + + layout.active = rd.use_simplify + + col = layout.column() col.prop(cscene, "use_camera_cull") - row = col.row() - row.active = cscene.use_camera_cull - row.prop(cscene, "camera_cull_margin") + sub = col.column() + sub.active = cscene.use_camera_cull + sub.prop(cscene, "camera_cull_margin") - col = split.column() + col = layout.column() col.prop(cscene, "use_distance_cull") - row = col.row() - row.active = cscene.use_distance_cull - row.prop(cscene, "distance_cull_margin", text="Distance") - - split = layout.split() - col = split.column() - col.prop(cscene, "ao_bounces") + sub = col.column() + sub.active = cscene.use_distance_cull + sub.prop(cscene, "distance_cull_margin", text="Distance") - 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) + layout.prop(cscene, "preview_pause", icon='PAUSE', text="") def get_panels(): @@ -1782,48 +1793,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__(): @@ -1838,17 +1815,32 @@ classes = ( CYCLES_MT_sampling_presets, CYCLES_MT_integrator_presets, CYCLES_RENDER_PT_sampling, + CYCLES_RENDER_PT_sampling_light, CYCLES_RENDER_PT_geometry, + CYCLES_RENDER_PT_geometry_subdivision, + CYCLES_RENDER_PT_geometry_volume, + CYCLES_RENDER_PT_geometry_hair, CYCLES_RENDER_PT_light_paths, + CYCLES_RENDER_PT_light_paths_max_bounces, + CYCLES_RENDER_PT_light_paths_caustics, CYCLES_RENDER_PT_motion_blur, + CYCLES_RENDER_PT_motion_blur_curve, CYCLES_RENDER_PT_film, + CYCLES_RENDER_PT_film_transparency, + CYCLES_RENDER_PT_film_pixel_filter, CYCLES_RENDER_PT_performance, - CYCLES_RENDER_PT_layer_options, + CYCLES_RENDER_PT_performance_threads, + CYCLES_RENDER_PT_performance_tiles, + CYCLES_RENDER_PT_performance_acceleration_structure, + CYCLES_RENDER_PT_performance_final_render, + CYCLES_RENDER_PT_performance_viewport, + 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, + CYCLES_CAMERA_PT_dof_aperture, + CYCLES_CAMERA_PT_dof_viewport, CYCLES_PT_context_material, CYCLES_OBJECT_PT_motion_blur, CYCLES_OBJECT_PT_cycles_settings, @@ -1864,28 +1856,28 @@ classes = ( CYCLES_WORLD_PT_mist, CYCLES_WORLD_PT_ray_visibility, CYCLES_WORLD_PT_settings, + CYCLES_WORLD_PT_settings_surface, + CYCLES_WORLD_PT_settings_volume, CYCLES_MATERIAL_PT_preview, CYCLES_MATERIAL_PT_surface, 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_MATERIAL_PT_settings_surface, + CYCLES_MATERIAL_PT_settings_volume, CYCLES_RENDER_PT_bake, CYCLES_RENDER_PT_debug, - CYCLES_PARTICLE_PT_curve_settings, CYCLES_SCENE_PT_simplify, + CYCLES_SCENE_PT_simplify_viewport, + CYCLES_SCENE_PT_simplify_render, + CYCLES_SCENE_PT_simplify_culling, ) 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(): @@ -1898,7 +1890,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(): |