diff options
Diffstat (limited to 'intern/cycles/blender/addon/ui.py')
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 2018 |
1 files changed, 1165 insertions, 853 deletions
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index d225c471177..4b0e179a388 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -17,28 +17,26 @@ # <pep8 compliant> import bpy -import _cycles +from bpy_extras.node_utils import find_node_input +from bl_ui.utils import PresetPanel -from bpy.types import ( - Panel, - Menu, -) +from bpy.types import Panel -class CYCLES_MT_sampling_presets(Menu): +class CYCLES_PT_sampling_presets(PresetPanel, Panel): 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_PT_integrator_presets(PresetPanel, Panel): 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,12 +47,25 @@ 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 + + +# Adapt properties editor panel to display in node editor. We have to +# copy the class rather than inherit due to the way bpy registration works. +def node_panel(cls): + node_cls = type('NODE_' + cls.__name__, cls.__bases__, dict(cls.__dict__)) + + node_cls.bl_space_type = 'NODE_EDITOR' + node_cls.bl_region_type = 'UI' + node_cls.bl_category = "Node" + if hasattr(node_cls, 'bl_parent_id'): + node_cls.bl_parent_id = 'NODE_' + node_cls.bl_parent_id + + return node_cls def get_device_type(context): - return context.user_preferences.addons[__package__].preferences.compute_device_type + return context.preferences.addons[__package__].preferences.compute_device_type def use_cpu(context): @@ -91,7 +102,7 @@ def show_device_active(context): cscene = context.scene.cycles if cscene.device != 'GPU': return True - return context.user_preferences.addons[__package__].preferences.has_active_device() + return context.preferences.addons[__package__].preferences.has_active_device() def draw_samples_info(layout, context): @@ -128,21 +139,23 @@ def draw_samples_info(layout, context): if use_branched_path(context) or (cscene.use_square_samples and integrator == 'PATH'): col = layout.column(align=True) col.scale_y = 0.6 - col.label("Total Samples:") + col.label(text="Total Samples:") col.separator() if integrator == 'PATH': - col.label("%s AA" % aa) + col.label(text="%s AA" % aa) else: - col.label("%s AA, %s Diffuse, %s Glossy, %s Transmission" % + col.label(text="%s AA, %s Diffuse, %s Glossy, %s Transmission" % (aa, d * aa, g * aa, t * aa)) col.separator() - col.label("%s AO, %s Mesh Light, %s Subsurface, %s Volume" % + col.label(text="%s AO, %s Mesh Light, %s Subsurface, %s Volume" % (ao * aa, ml * aa, sss * aa, vol * aa)) class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel): bl_label = "Sampling" - bl_options = {'DEFAULT_CLOSED'} + + def draw_header_preset(self, context): + CYCLES_PT_sampling_presets.draw_panel_header(self.layout) def draw(self, context): layout = self.layout @@ -150,168 +163,298 @@ class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel): 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 + layout.use_property_decorate = False - row = layout.row() - sub = row.row() - sub.prop(cscene, "progressive", text="") - row.prop(cscene, "use_square_samples") + layout.prop(cscene, "progressive") - split = layout.split() + if cscene.progressive == 'PATH' or use_branched_path(context) is False: + col = layout.column(align=True) + col.prop(cscene, "samples", text="Render") + col.prop(cscene, "preview_samples", text="Viewport") - col = split.column() - sub = col.column(align=True) - sub.label("Settings:") + draw_samples_info(layout, context) + else: + col = layout.column(align=True) + col.prop(cscene, "aa_samples", text="Render") + col.prop(cscene, "preview_aa_samples", text="Viewport") - 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") +class CYCLES_RENDER_PT_sampling_sub_samples(CyclesButtonsPanel, Panel): + bl_label = "Sub Samples" + bl_parent_id = "CYCLES_RENDER_PT_sampling" - 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") - else: - sub.label(text="AA Samples:") - sub.prop(cscene, "aa_samples", text="Render") - sub.prop(cscene, "preview_aa_samples", text="Preview") + @classmethod + def poll(self, context): + scene = context.scene + cscene = scene.cycles + return cscene.progressive != 'PATH' and use_branched_path(context) - 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") + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False - subsub = sub.row(align=True) - subsub.active = use_sample_all_lights(context) - subsub.prop(cscene, "mesh_light_samples", text="Mesh Light") + scene = context.scene + cscene = scene.cycles + + col = layout.column(align=True) + 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") + + draw_samples_info(layout, context) + + +class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel): + bl_label = "Advanced" + bl_parent_id = "CYCLES_RENDER_PT_sampling" + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + scene = context.scene + cscene = scene.cycles + + 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") + + layout.prop(cscene, "use_square_samples") - sub.prop(cscene, "subsurface_samples", text="Subsurface") - sub.prop(cscene, "volume_samples", text="Volume") + layout.separator() + + col = layout.column(align=True) + col.prop(cscene, "light_sampling_threshold", text="Light Threshold") + if cscene.progressive != 'PATH' and use_branched_path(context): 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") - - for rl in scene.render.layers: - if rl.samples > 0: + for view_layer in scene.view_layers: + if view_layer.samples > 0: layout.separator() layout.row().prop(cscene, "use_layer_samples") break - draw_samples_info(layout, context) + +class CYCLES_RENDER_PT_sampling_total(CyclesButtonsPanel, Panel): + bl_label = "Total Samples" + bl_parent_id = "CYCLES_RENDER_PT_sampling" + + @classmethod + def poll(self, context): + scene = context.scene + cscene = scene.cycles + + if cscene.use_square_samples: + return True + + return cscene.progressive != 'PATH' and use_branched_path(context) + + def draw(self, context): + layout = self.layout + cscene = context.scene.cycles + integrator = cscene.progressive + + # Calculate sample values + if integrator == 'PATH': + aa = cscene.samples + if cscene.use_square_samples: + aa = aa * aa + else: + aa = cscene.aa_samples + d = cscene.diffuse_samples + g = cscene.glossy_samples + t = cscene.transmission_samples + ao = cscene.ao_samples + ml = cscene.mesh_light_samples + sss = cscene.subsurface_samples + vol = cscene.volume_samples + + if cscene.use_square_samples: + aa = aa * aa + d = d * d + g = g * g + t = t * t + ao = ao * ao + ml = ml * ml + sss = sss * sss + vol = vol * vol + + col = layout.column(align=True) + col.scale_y = 0.6 + if integrator == 'PATH': + col.label(text="%s AA" % aa) + else: + col.label(text="%s AA, %s Diffuse, %s Glossy, %s Transmission" % + (aa, d * aa, g * aa, t * aa)) + col.separator() + col.label(text="%s AO, %s Mesh Light, %s Subsurface, %s Volume" % + (ao * aa, ml * aa, sss * aa, vol * aa)) -class CYCLES_RENDER_PT_geometry(CyclesButtonsPanel, Panel): - bl_label = "Geometry" +class CYCLES_RENDER_PT_subdivision(CyclesButtonsPanel, Panel): + bl_label = "Subdivision" bl_options = {'DEFAULT_CLOSED'} + @classmethod + def poll(self, context): + return (context.scene.render.engine == 'CYCLES') and (context.scene.cycles.feature_set == 'EXPERIMENTAL') + def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False 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") + + +class CYCLES_RENDER_PT_hair(CyclesButtonsPanel, Panel): + bl_label = "Hair" + bl_options = {'DEFAULT_CLOSED'} - col = split.column() - col.prop(cscene, "offscreen_dicing_scale", text="Offscreen Scale") - col.prop(cscene, "max_subdivisions") + def draw_header(self, context): + layout = self.layout + scene = context.scene + ccscene = scene.cycles_curves - layout.prop(cscene, "dicing_camera") + layout.prop(ccscene, "use_curves", text="") - layout.separator() + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False - layout.label("Hair:") - layout.prop(ccscene, "use_curves", text="Use Hair") - col = layout.column() - col.active = ccscene.use_curves + scene = context.scene + ccscene = scene.cycles_curves - col.prop(ccscene, "primitive", text="Primitive") - col.prop(ccscene, "shape", text="Shape") + 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_volumes(CyclesButtonsPanel, Panel): + bl_label = "Volumes" + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + scene = context.scene + cscene = scene.cycles + + col = layout.column() + col.prop(cscene, "volume_step_size", text="Step Size") + col.prop(cscene, "volume_max_steps", text="Max Steps") class CYCLES_RENDER_PT_light_paths(CyclesButtonsPanel, Panel): bl_label = "Light Paths" bl_options = {'DEFAULT_CLOSED'} + def draw_header_preset(self, context): + CYCLES_PT_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 + layout.use_property_decorate = False 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_clamping(CyclesButtonsPanel, Panel): + bl_label = "Clamping" + bl_parent_id = "CYCLES_RENDER_PT_light_paths" - col.separator() + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False - col.prop(cscene, "caustics_reflective") - col.prop(cscene, "caustics_refractive") - col.prop(cscene, "blur_glossy") + scene = context.scene + cscene = scene.cycles - col = split.column() + col = layout.column(align=True) + col.prop(cscene, "sample_clamp_direct", text="Direct Light") + col.prop(cscene, "sample_clamp_indirect", text="Indirect Light") - 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_light_paths_caustics(CyclesButtonsPanel, Panel): + bl_label = "Caustics" + bl_parent_id = "CYCLES_RENDER_PT_light_paths" + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + scene = context.scene + cscene = scene.cycles + + col = layout.column() + col.prop(cscene, "blur_glossy") + col.prop(cscene, "caustics_reflective") + col.prop(cscene, "caustics_refractive") class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel): @@ -325,6 +468,8 @@ class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False scene = context.scene cscene = scene.cycles @@ -334,9 +479,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 + layout.use_property_decorate = False + + scene = context.scene + 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) @@ -348,40 +513,66 @@ 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 + layout.use_property_decorate = False + 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 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 + layout.use_property_decorate = False + 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" + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + 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,320 +580,434 @@ class CYCLES_RENDER_PT_performance(CyclesButtonsPanel, Panel): bl_options = {'DEFAULT_CLOSED'} def draw(self, context): + pass + + +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 + layout.use_property_decorate = False scene = context.scene rd = scene.render - cscene = scene.cycles - split = layout.split() - - col = split.column(align=True) + 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 + layout.use_property_decorate = False + + scene = context.scene + rd = scene.render + cscene = scene.cycles + + 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() - 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" - col.separator() + def draw(self, context): + import _cycles + + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + scene = context.scene + cscene = scene.cycles + + col = layout.column() - col.label(text="Acceleration structure:") if _cycles.with_embree: row = col.row() row.active = use_cpu(context) row.prop(cscene, "use_bvh_embree") - row = col.row() col.prop(cscene, "debug_use_spatial_splits") - row = col.row() - row.active = not cscene.use_bvh_embree or not _cycles.with_embree - row.prop(cscene, "debug_use_hair_bvh") + sub = col.column() + sub.active = not cscene.use_bvh_embree or not _cycles.with_embree + sub.prop(cscene, "debug_use_hair_bvh") + sub = col.column() + sub.active = not cscene.debug_use_spatial_splits and not cscene.use_bvh_embree + sub.prop(cscene, "debug_bvh_time_steps") + - row = col.row() - row.active = not cscene.debug_use_spatial_splits and not cscene.use_bvh_embree - 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" + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + scene = context.scene + rd = scene.render 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" def draw(self, context): layout = self.layout - with_freestyle = bpy.app.build_options.freestyle + layout.use_property_split = True + layout.use_property_decorate = False 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_options = {'DEFAULT_CLOSED'} + bl_context = "view_layer" - split = layout.split() + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False - col = split.column() - col.label(text="Material:") - col.prop(rl, "material_override", text="") - col.separator() - col.prop(rl, "samples") + with_freestyle = bpy.app.build_options.freestyle - 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") + scene = context.scene + rd = scene.render + view_layer = context.view_layer + + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) + + col = flow.column() + col.prop(view_layer, "use_sky", text="Environment") + col = flow.column() + col.prop(view_layer, "use_ao", text="Ambient Occlusion") + col = flow.column() + col.prop(view_layer, "use_solid", text="Surfaces") + col = flow.column() + col.prop(view_layer, "use_strand", text="Hair") if with_freestyle: - row = col.row() - row.prop(rl, "use_freestyle", "Use Freestyle") - row.active = rd.use_freestyle + col = flow.column() + col.prop(view_layer, "use_freestyle", text="Freestyle") + col.active = rd.use_freestyle -class CYCLES_RENDER_PT_layer_passes(CyclesButtonsPanel, Panel): +class CYCLES_RENDER_PT_override(CyclesButtonsPanel, Panel): + bl_label = "Override" + bl_options = {'DEFAULT_CLOSED'} + bl_context = "view_layer" + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + view_layer = context.view_layer + + layout.prop(view_layer, "material_override") + layout.prop(view_layer, "samples") + + +class CYCLES_RENDER_PT_passes(CyclesButtonsPanel, Panel): bl_label = "Passes" - bl_context = "render_layer" + bl_context = "view_layer" bl_options = {'DEFAULT_CLOSED'} def draw(self, context): + pass + + +class CYCLES_RENDER_PT_passes_data(CyclesButtonsPanel, Panel): + bl_label = "Data" + bl_context = "view_layer" + bl_parent_id = "CYCLES_RENDER_PT_passes" + + def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False scene = context.scene rd = scene.render - rl = rd.layers.active - crl = rl.cycles + view_layer = context.view_layer + cycles_view_layer = view_layer.cycles + + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) + col = flow.column() + col.prop(view_layer, "use_pass_combined") + col = flow.column() + col.prop(view_layer, "use_pass_z") + col = flow.column() + col.prop(view_layer, "use_pass_mist") + col = flow.column() + col.prop(view_layer, "use_pass_normal") + col = flow.column() + col.prop(view_layer, "use_pass_vector") + col.active = not rd.use_motion_blur + col = flow.column() + col.prop(view_layer, "use_pass_uv") + col = flow.column() + col.prop(view_layer, "use_pass_object_index") + col = flow.column() + col.prop(view_layer, "use_pass_material_index") - split = layout.split() + layout.separator() - 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") - row = col.row() - row.prop(rl, "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.separator() - col.prop(rl, "use_pass_shadow") - col.prop(rl, "use_pass_ambient_occlusion") - col.separator() - col.prop(crl, "denoising_store_passes", text="Denoising Data") - col.separator() - col.prop(rl, "pass_alpha_threshold") + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) + col = flow.column() + col.prop(cycles_view_layer, "denoising_store_passes", text="Denoising Data") + col = flow.column() + col.prop(cycles_view_layer, "pass_debug_render_time", text="Render Time") - 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) - 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) - 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) - 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) - 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) + layout.separator() - col.separator() - col.prop(rl, "use_pass_emit", text="Emission") - col.prop(rl, "use_pass_environment") + layout.prop(view_layer, "pass_alpha_threshold") - col = layout.column() - col.prop(crl, "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") - - crl = rl.cycles - layout.label("Cryptomatte:") - row = layout.row(align=True) - row.prop(crl, "use_pass_crypto_object", text="Object", toggle=True) - row.prop(crl, "use_pass_crypto_material", text="Material", toggle=True) - row.prop(crl, "use_pass_crypto_asset", text="Asset", toggle=True) - row = layout.row(align=True) - row.prop(crl, "pass_crypto_depth") - row = layout.row(align=True) - row.active = use_cpu(context) - row.prop(crl, "pass_crypto_accurate", text="Accurate Mode") -class CYCLES_RENDER_PT_views(CyclesButtonsPanel, Panel): - bl_label = "Views" - bl_context = "render_layer" - bl_options = {'DEFAULT_CLOSED'} +class CYCLES_RENDER_PT_passes_light(CyclesButtonsPanel, Panel): + bl_label = "Light" + bl_context = "view_layer" + bl_parent_id = "CYCLES_RENDER_PT_passes" + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + view_layer = context.view_layer + cycles_view_layer = view_layer.cycles + + split = layout.split(factor=0.35) + split.use_property_split = False + split.label(text="Diffuse") + row = split.row(align=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) + + split = layout.split(factor=0.35) + split.use_property_split = False + split.label(text="Glossy") + row = split.row(align=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) + + split = layout.split(factor=0.35) + split.use_property_split = False + split.label(text="Transmission") + row = split.row(align=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) + + split = layout.split(factor=0.35) + split.use_property_split = False + split.label(text="Subsurface") + row = split.row(align=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) + + split = layout.split(factor=0.35) + split.use_property_split = False + split.label(text="Volume") + row = split.row(align=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 = layout.column(align=True) + col.prop(view_layer, "use_pass_emit", text="Emission") + col.prop(view_layer, "use_pass_environment") + col.prop(view_layer, "use_pass_shadow") + col.prop(view_layer, "use_pass_ambient_occlusion", text="Ambient Occlusion") - def draw_header(self, context): - rd = context.scene.render - self.layout.prop(rd, "use_multiview", text="") + +class CYCLES_RENDER_PT_passes_crypto(CyclesButtonsPanel, Panel): + bl_label = "Cryptomatte" + bl_context = "view_layer" + bl_parent_id = "CYCLES_RENDER_PT_passes" def draw(self, context): + import _cycles + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False - scene = context.scene - rd = scene.render - rv = rd.views.active + cycles_view_layer = context.view_layer.cycles + + row = layout.row(align=True) + row.use_property_split = False + row.prop(cycles_view_layer, "use_pass_crypto_object", text="Object", toggle=True) + row.prop(cycles_view_layer, "use_pass_crypto_material", text="Material", toggle=True) + row.prop(cycles_view_layer, "use_pass_crypto_asset", text="Asset", toggle=True) - layout.active = rd.use_multiview - basic_stereo = (rd.views_format == 'STEREO_3D') + layout.prop(cycles_view_layer, "pass_crypto_depth", text="Levels") - row = layout.row() - row.prop(rd, "views_format", expand=True) + row = layout.row(align=True) + row.active = use_cpu(context) + row.prop(cycles_view_layer, "pass_crypto_accurate", text="Accurate Mode") - 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="") +class CYCLES_RENDER_PT_passes_debug(CyclesButtonsPanel, Panel): + bl_label = "Debug" + bl_context = "view_layer" + bl_parent_id = "CYCLES_RENDER_PT_passes" - else: - row = layout.row() - row.template_list("RENDERLAYER_UL_renderviews", "name", rd, "views", rd.views, "active_index", rows=2) + @classmethod + def poll(cls, context): + import _cycles + return _cycles.with_cycles_debug - col = row.column(align=True) - col.operator("scene.render_view_add", icon='ZOOMIN', text="") - col.operator("scene.render_view_remove", icon='ZOOMOUT', text="") + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False - row = layout.row() - row.label(text="Camera Suffix:") - row.prop(rv, "camera_suffix", text="") + cycles_view_layer = context.view_layer.cycles + + layout.prop(cycles_view_layer, "pass_debug_bvh_traversed_nodes") + layout.prop(cycles_view_layer, "pass_debug_bvh_traversed_instances") + layout.prop(cycles_view_layer, "pass_debug_bvh_intersections") + layout.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 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 + layout.use_property_decorate = False 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 split = layout.split() - split.active = crl.use_denoising + split.active = cycles_view_layer.use_denoising + + layout = layout.column(align=True) + layout.prop(cycles_view_layer, "denoising_radius", text="Radius") + layout.prop(cycles_view_layer, "denoising_strength", slider=True, text="Strength") + layout.prop(cycles_view_layer, "denoising_feature_strength", slider=True, text="Feature Strength") + layout.prop(cycles_view_layer, "denoising_relative_pca") + + layout.separator() + + split = layout.split(factor=0.5) + split.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes col = split.column() - sub = col.column(align=True) - sub.prop(crl, "denoising_radius", text="Radius") - sub.prop(crl, "denoising_strength", slider=True, text="Strength") + col.alignment = 'RIGHT' + col.label(text="Diffuse") + + row = split.row(align=True) + row.use_property_split = False + 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(factor=0.5) + split.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes 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") + col.alignment = 'RIGHT' + col.label(text="Glossy") - layout.separator() + row = split.row(align=True) + row.use_property_split = False + row.prop(cycles_view_layer, "denoising_glossy_direct", text="Direct", toggle=True) + row.prop(cycles_view_layer, "denoising_glossy_indirect", text="Indirect", toggle=True) - row = layout.row() - row.active = crl.use_denoising or crl.denoising_store_passes - 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) + split = layout.split(factor=0.5) + split.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes - row = layout.row() - row.active = crl.use_denoising or crl.denoising_store_passes - 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 = split.column() + col.alignment = 'RIGHT' + col.label(text="Transmission") - row = layout.row() - row.active = crl.use_denoising or crl.denoising_store_passes - 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) + row = split.row(align=True) + row.use_property_split = False + row.prop(cycles_view_layer, "denoising_transmission_direct", text="Direct", toggle=True) + row.prop(cycles_view_layer, "denoising_transmission_indirect", text="Indirect", toggle=True) - row = layout.row() - row.active = crl.use_denoising or crl.denoising_store_passes - 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) + split = layout.split(factor=0.5) + split.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes + + col = split.column() + col.alignment = 'RIGHT' + col.label(text="Subsurface") + + row = split.row(align=True) + row.use_property_split = False + 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): bl_label = "Post Processing" bl_options = {'DEFAULT_CLOSED'} + bl_context = "output" def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False 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): @@ -715,45 +1020,69 @@ 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 - dof_options = cam.gpu_dof 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") - hq_support = dof_options.is_hq_supported - sub = col.column(align=True) - sub.label("Viewport:") - subhq = sub.column() - subhq.active = hq_support - subhq.prop(dof_options, "use_high_quality") - sub.prop(dof_options, "fstop") - if dof_options.use_high_quality and hq_support: - sub.prop(dof_options, "blades") - col = split.column() +class CYCLES_CAMERA_PT_dof_aperture(CyclesButtonsPanel, Panel): + bl_label = "Aperture" + bl_parent_id = "CYCLES_CAMERA_PT_dof" - col.label("Aperture:") - sub = col.column(align=True) - sub.prop(ccam, "aperture_type", text="") + @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, columns=0, even_columns=True, even_rows=False, align=False) + + cam = context.camera + ccam = cam.cycles + + col = flow.column() + col.prop(ccam, "aperture_type") if ccam.aperture_type == 'RADIUS': - sub.prop(ccam, "aperture_size", text="Size") + col.prop(ccam, "aperture_size", text="Size") elif ccam.aperture_type == 'FSTOP': - sub.prop(ccam, "aperture_fstop", text="Number") + col.prop(ccam, "aperture_fstop", text="Number") + col.separator() - 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") + 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, columns=0, even_columns=True, even_rows=False, align=False) + + cam = context.camera + dof_options = cam.gpu_dof + + sub = flow.column(align=True) + sub.prop(dof_options, "fstop") + sub.prop(dof_options, "blades") class CYCLES_PT_context_material(CyclesButtonsPanel, Panel): @@ -763,7 +1092,10 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel): @classmethod def poll(cls, context): - return (context.material or context.object) and CyclesButtonsPanel.poll(context) + if context.active_object and context.active_object.type == 'GPENCIL': + return False + else: + return (context.material or context.object) and CyclesButtonsPanel.poll(context) def draw(self, context): layout = self.layout @@ -784,10 +1116,10 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel): row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=rows) col = row.column(align=True) - col.operator("object.material_slot_add", icon='ZOOMIN', text="") - col.operator("object.material_slot_remove", icon='ZOOMOUT', text="") + col.operator("object.material_slot_add", icon='ADD', text="") + col.operator("object.material_slot_remove", icon='REMOVE', text="") - col.menu("MATERIAL_MT_specials", icon='DOWNARROW_HLT', text="") + col.menu("MATERIAL_MT_context_menu", icon='DOWNARROW_HLT', text="") if is_sortable: col.separator() @@ -801,7 +1133,7 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel): row.operator("object.material_slot_select", text="Select") row.operator("object.material_slot_deselect", text="Deselect") - split = layout.split(percentage=0.65) + split = layout.split(factor=0.65) if ob: split.template_ID(ob, "active_material", new="material.new") @@ -827,7 +1159,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.instance_type == 'COLLECTION' and ob.instance_collection: return True # TODO(sergey): More duplicator types here? return False @@ -871,68 +1203,80 @@ class CYCLES_OBJECT_PT_cycles_settings(CyclesButtonsPanel, Panel): def poll(cls, context): 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 and ((ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'LIGHT'}) or + (ob.instance_type == 'COLLECTION' and ob.instance_collection))) + + def draw(self, context): + pass + + +class CYCLES_OBJECT_PT_cycles_settings_ray_visibility(CyclesButtonsPanel, Panel): + bl_label = "Ray Visibility" + bl_parent_id = "CYCLES_OBJECT_PT_cycles_settings" + bl_context = "object" def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False scene = context.scene - cscene = scene.cycles ob = context.object cob = ob.cycles visibility = ob.cycles_visibility - layout.label(text="Ray Visibility:") - flow = layout.column_flow() + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - flow.prop(visibility, "camera") - flow.prop(visibility, "diffuse") - flow.prop(visibility, "glossy") - flow.prop(visibility, "transmission") - flow.prop(visibility, "scatter") + col = flow.column() + col.prop(visibility, "camera") + col = flow.column() + col.prop(visibility, "diffuse") + col = flow.column() + col.prop(visibility, "glossy") + col = flow.column() + col.prop(visibility, "transmission") + col = flow.column() + col.prop(visibility, "scatter") - if ob.type != 'LAMP': - flow.prop(visibility, "shadow") + if ob.type != 'LIGHT': + col = flow.column() + col.prop(visibility, "shadow") - row = layout.row() - row.prop(cob, "is_shadow_catcher") - row.prop(cob, "is_holdout") + layout.separator() - col = layout.column() - col.label(text="Performance:") - row = col.row() - sub = row.row() - sub.active = scene.render.use_simplify and cscene.use_camera_cull - sub.prop(cob, "use_camera_cull") + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - sub = row.row() - sub.active = scene.render.use_simplify and cscene.use_distance_cull - sub.prop(cob, "use_distance_cull") + col = flow.column() + col.prop(cob, "is_shadow_catcher") + col = flow.column() + col.prop(cob, "is_holdout") -def find_node(material, nodetype): - if material and material.node_tree: - ntree = material.node_tree +class CYCLES_OBJECT_PT_cycles_settings_performance(CyclesButtonsPanel, Panel): + bl_label = "Performance" + bl_parent_id = "CYCLES_OBJECT_PT_cycles_settings" + bl_context = "object" - 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 draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + scene = context.scene + cscene = scene.cycles + ob = context.object + cob = ob.cycles + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) -def find_node_input(node, name): - for input in node.inputs: - if input.name == name: - return input + col = flow.column() + col.active = scene.render.use_simplify and cscene.use_camera_cull + col.prop(cob, "use_camera_cull") - return None + col = flow.column() + col.active = scene.render.use_simplify and cscene.use_distance_cull + col.prop(cob, "use_distance_cull") def panel_node_draw(layout, id_data, output_type, input_name): @@ -942,127 +1286,130 @@ def panel_node_draw(layout, id_data, output_type, input_name): ntree = id_data.node_tree - node = find_node(id_data, output_type) - if not node: - layout.label(text="No output node") - else: + node = ntree.get_output_node('CYCLES') + 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 -class CYCLES_LAMP_PT_preview(CyclesButtonsPanel, Panel): +class CYCLES_LIGHT_PT_preview(CyclesButtonsPanel, Panel): bl_label = "Preview" bl_context = "data" bl_options = {'DEFAULT_CLOSED'} @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.light and + not ( + context.light.type == 'AREA' and + context.light.cycles.is_portal + ) and + CyclesButtonsPanel.poll(context) + ) def draw(self, context): - self.layout.template_preview(context.lamp) + self.layout.template_preview(context.light) -class CYCLES_LAMP_PT_lamp(CyclesButtonsPanel, Panel): - bl_label = "Lamp" +class CYCLES_LIGHT_PT_light(CyclesButtonsPanel, Panel): + bl_label = "Light" bl_context = "data" @classmethod def poll(cls, context): - return context.lamp and CyclesButtonsPanel.poll(context) + return context.light and CyclesButtonsPanel.poll(context) def draw(self, context): layout = self.layout - lamp = context.lamp - clamp = lamp.cycles - # cscene = context.scene.cycles + light = context.light + clamp = light.cycles - layout.prop(lamp, "type", expand=True) + layout.use_property_decorate = False - split = layout.split() - col = split.column(align=True) + if self.bl_space_type == 'PROPERTIES': + layout.row().prop(light, "type", expand=True) + layout.use_property_split = True + else: + layout.use_property_split = True + layout.row().prop(light, "type") - if lamp.type in {'POINT', 'SUN', 'SPOT'}: - col.prop(lamp, "shadow_soft_size", text="Size") - elif lamp.type == 'AREA': - col.prop(lamp, "shape", text="") + col = layout.column() + + if light.type in {'POINT', 'SUN', 'SPOT'}: + col.prop(light, "shadow_soft_size", text="Size") + elif light.type == 'AREA': + col.prop(light, "shape", text="Shape") sub = col.column(align=True) - if lamp.shape == 'SQUARE': - sub.prop(lamp, "size") - elif lamp.shape == 'RECTANGLE': - sub.prop(lamp, "size", text="Size X") - sub.prop(lamp, "size_y", text="Size Y") + if light.shape in {'SQUARE', 'DISK'}: + sub.prop(light, "size") + elif light.shape in {'RECTANGLE', 'ELLIPSE'}: + sub.prop(light, "size", text="Size X") + sub.prop(light, "size_y", text="Y") - if not (lamp.type == 'AREA' and clamp.is_portal): - sub = col.column(align=True) + if not (light.type == 'AREA' and clamp.is_portal): + sub = col.column() if use_branched_path(context): subsub = sub.row(align=True) subsub.active = use_sample_all_lights(context) subsub.prop(clamp, "samples") sub.prop(clamp, "max_bounces") - col = split.column() - sub = col.column(align=True) - sub.active = not (lamp.type == 'AREA' and clamp.is_portal) + sub.active = not (light.type == 'AREA' and clamp.is_portal) sub.prop(clamp, "cast_shadow") sub.prop(clamp, "use_multiple_importance_sampling", text="Multiple Importance") - if lamp.type == 'AREA': + if light.type == 'AREA': col.prop(clamp, "is_portal", text="Portal") - if lamp.type == 'HEMI': - layout.label(text="Not supported, interpreted as sun lamp") - -class CYCLES_LAMP_PT_nodes(CyclesButtonsPanel, Panel): +class CYCLES_LIGHT_PT_nodes(CyclesButtonsPanel, Panel): bl_label = "Nodes" bl_context = "data" @classmethod def poll(cls, context): - return context.lamp and not (context.lamp.type == 'AREA' and - context.lamp.cycles.is_portal) and \ + return context.light and not (context.light.type == 'AREA' and + context.light.cycles.is_portal) and \ CyclesButtonsPanel.poll(context) def draw(self, context): layout = self.layout - lamp = context.lamp - if not panel_node_draw(layout, lamp, 'OUTPUT_LAMP', 'Surface'): - layout.prop(lamp, "color") + light = context.light + if not panel_node_draw(layout, light, 'OUTPUT_LIGHT', 'Surface'): + layout.prop(light, "color") -class CYCLES_LAMP_PT_spot(CyclesButtonsPanel, Panel): +class CYCLES_LIGHT_PT_spot(CyclesButtonsPanel, Panel): bl_label = "Spot Shape" bl_context = "data" @classmethod def poll(cls, context): - lamp = context.lamp - return (lamp and lamp.type == 'SPOT') and CyclesButtonsPanel.poll(context) + light = context.light + return (light and light.type == 'SPOT') and CyclesButtonsPanel.poll(context) def draw(self, context): layout = self.layout + light = context.light + layout.use_property_split = True + layout.use_property_decorate = False - lamp = context.lamp - - split = layout.split() - - col = split.column() - sub = col.column() - sub.prop(lamp, "spot_size", text="Size") - sub.prop(lamp, "spot_blend", text="Blend", slider=True) - - col = split.column() - col.prop(lamp, "show_cone") + col = layout.column() + col.prop(light, "spot_size", text="Size") + col.prop(light, "spot_blend", text="Blend", slider=True) + col.prop(light, "show_cone") class CYCLES_WORLD_PT_preview(CyclesButtonsPanel, Panel): @@ -1092,7 +1439,7 @@ class CYCLES_WORLD_PT_surface(CyclesButtonsPanel, Panel): world = context.world if not panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Surface'): - layout.prop(world, "horizon_color", text="Color") + layout.prop(world, "color") class CYCLES_WORLD_PT_volume(CyclesButtonsPanel, Panel): @@ -1115,6 +1462,7 @@ class CYCLES_WORLD_PT_volume(CyclesButtonsPanel, Panel): class CYCLES_WORLD_PT_ambient_occlusion(CyclesButtonsPanel, Panel): bl_label = "Ambient Occlusion" bl_context = "world" + bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): @@ -1126,15 +1474,17 @@ class CYCLES_WORLD_PT_ambient_occlusion(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False 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): @@ -1146,8 +1496,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 @@ -1199,35 +1549,67 @@ class CYCLES_WORLD_PT_settings(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False - world = context.world - cworld = world.cycles - # cscene = context.scene.cycles + layout.column() - split = layout.split() - 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 + layout.use_property_decorate = False + + world = context.world + cworld = world.cycles - col.label(text="Surface:") + 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 + layout.use_property_decorate = False + + 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") @@ -1238,7 +1620,8 @@ class CYCLES_MATERIAL_PT_preview(CyclesButtonsPanel, Panel): @classmethod def poll(cls, context): - return context.material and CyclesButtonsPanel.poll(context) + mat = context.material + return mat and (not mat.grease_pencil) and CyclesButtonsPanel.poll(context) def draw(self, context): self.layout.template_preview(context.material) @@ -1250,7 +1633,8 @@ class CYCLES_MATERIAL_PT_surface(CyclesButtonsPanel, Panel): @classmethod def poll(cls, context): - return context.material and CyclesButtonsPanel.poll(context) + mat = context.material + return mat and (not mat.grease_pencil) and CyclesButtonsPanel.poll(context) def draw(self, context): layout = self.layout @@ -1268,7 +1652,7 @@ class CYCLES_MATERIAL_PT_volume(CyclesButtonsPanel, Panel): @classmethod def poll(cls, context): mat = context.material - return mat and mat.node_tree and CyclesButtonsPanel.poll(context) + return mat and (not mat.grease_pencil) and mat.node_tree and CyclesButtonsPanel.poll(context) def draw(self, context): layout = self.layout @@ -1286,7 +1670,7 @@ class CYCLES_MATERIAL_PT_displacement(CyclesButtonsPanel, Panel): @classmethod def poll(cls, context): mat = context.material - return mat and mat.node_tree and CyclesButtonsPanel.poll(context) + return mat and (not mat.grease_pencil) and mat.node_tree and CyclesButtonsPanel.poll(context) def draw(self, context): layout = self.layout @@ -1298,301 +1682,221 @@ class CYCLES_MATERIAL_PT_displacement(CyclesButtonsPanel, Panel): class CYCLES_MATERIAL_PT_settings(CyclesButtonsPanel, Panel): bl_label = "Settings" bl_context = "material" - - @classmethod - def poll(cls, context): - return context.material and CyclesButtonsPanel.poll(context) - - def draw(self, context): - layout = self.layout - - 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") - - -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 + return mat and (not mat.grease_pencil) and CyclesButtonsPanel.poll(context) + @staticmethod + def draw_shared(self, mat): 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") - + layout.use_property_split = True + layout.use_property_decorate = False -class CYCLES_TEXTURE_PT_context(CyclesButtonsPanel, Panel): - bl_label = "" - bl_context = "texture" - bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'CYCLES'} + layout.prop(mat, "pass_index") def draw(self, context): - layout = self.layout + self.draw_shared(self, context.material) - 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 +class CYCLES_MATERIAL_PT_settings_surface(CyclesButtonsPanel, Panel): + bl_label = "Surface" + bl_parent_id = "CYCLES_MATERIAL_PT_settings" + bl_context = "material" - if not (use_pin_id and isinstance(pin_id, bpy.types.Texture)): - pin_id = None + @staticmethod + def draw_shared(self, mat): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False - if not pin_id: - layout.template_texture_user() + cmat = mat.cycles - if user or pin_id: - layout.separator() + 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") - split = layout.split(percentage=0.65) - col = split.column() + def draw(self, context): + self.draw_shared(self, context.material) - 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_MATERIAL_PT_settings_volume(CyclesButtonsPanel, Panel): + bl_label = "Volume" + bl_parent_id = "CYCLES_MATERIAL_PT_settings" + bl_context = "material" + @staticmethod + def draw_shared(self, context, mat): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False -class CYCLES_TEXTURE_PT_node(CyclesButtonsPanel, Panel): - bl_label = "Node" - bl_context = "texture" + cmat = mat.cycles - @classmethod - def poll(cls, context): - node = context.texture_node - return node and CyclesButtonsPanel.poll(context) + 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") def draw(self, context): - layout = self.layout + self.draw_shared(self, context, context.material) - 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) +class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel): + bl_label = "Bake" + bl_context = "render" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'CYCLES'} def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False # No animation. - 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:") + scene = context.scene + cscene = scene.cycles + cbk = scene.render.bake + rd = scene.render - row = layout.row() - row.prop(mapping, "mapping_x", text="") - row.prop(mapping, "mapping_y", text="") - row.prop(mapping, "mapping_z", text="") + if rd.use_bake_multires: + layout.operator("object.bake_image", icon='RENDER_STILL') + layout.prop(rd, "use_bake_multires") + layout.prop(rd, "bake_type") + else: + layout.operator("object.bake", icon='RENDER_STILL').type = cscene.bake_type + layout.prop(rd, "use_bake_multires") + layout.prop(cscene, "bake_type") -class CYCLES_TEXTURE_PT_colors(CyclesButtonsPanel, Panel): - bl_label = "Color" - bl_context = "texture" - bl_options = {'DEFAULT_CLOSED'} +class CYCLES_RENDER_PT_bake_influence(CyclesButtonsPanel, Panel): + bl_label = "Influence" + bl_context = "render" + bl_parent_id = "CYCLES_RENDER_PT_bake" + COMPAT_ENGINES = {'CYCLES'} @classmethod def poll(cls, context): - # node = context.texture_node - return False - # return node and CyclesButtonsPanel.poll(context) + scene = context.scene + cscene = scene.cycles + rd = scene.render + if rd.use_bake_multires == False and cscene.bake_type in { + 'NORMAL', 'COMBINED', 'DIFFUSE', 'GLOSSY', 'TRANSMISSION', 'SUBSURFACE'}: + return True def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False # No animation. - node = context.texture_node + scene = context.scene + cscene = scene.cycles + cbk = scene.render.bake + rd = scene.render - mapping = node.color_mapping + col = layout.column() - split = layout.split() + if cscene.bake_type == 'NORMAL': + col.prop(cbk, "normal_space", text="Space") - 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="") + sub = col.column(align=True) + sub.prop(cbk, "normal_r", text="Swizzle R") + sub.prop(cbk, "normal_g", text="G") + sub.prop(cbk, "normal_b", text="B") - col = split.column() - col.label(text="Adjust:") - col.prop(mapping, "brightness") - col.prop(mapping, "contrast") - col.prop(mapping, "saturation") + 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) - layout.separator() + flow = col.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=True) - layout.prop(mapping, "use_color_ramp", text="Ramp") - if mapping.use_color_ramp: - layout.template_color_ramp(mapping, "color_ramp", expand=True) + flow.active = cbk.use_pass_direct or cbk.use_pass_indirect + flow.prop(cbk, "use_pass_diffuse") + flow.prop(cbk, "use_pass_glossy") + flow.prop(cbk, "use_pass_transmission") + flow.prop(cbk, "use_pass_subsurface") + flow.prop(cbk, "use_pass_ambient_occlusion") + flow.prop(cbk, "use_pass_emit") + + elif cscene.bake_type in {'DIFFUSE', 'GLOSSY', 'TRANSMISSION', 'SUBSURFACE'}: + 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) + row.prop(cbk, "use_pass_color", toggle=True) -class CYCLES_PARTICLE_PT_textures(CyclesButtonsPanel, Panel): - bl_label = "Textures" - bl_context = "particle" +class CYCLES_RENDER_PT_bake_selected_to_active(CyclesButtonsPanel, Panel): + bl_label = "Selected to Active" + bl_context = "render" + bl_parent_id = "CYCLES_RENDER_PT_bake" bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'CYCLES'} @classmethod def poll(cls, context): - psys = context.particle_system - return psys and CyclesButtonsPanel.poll(context) + scene = context.scene + rd = scene.render + return rd.use_bake_multires == False + + def draw_header(self, context): + scene = context.scene + cbk = scene.render.bake + self.layout.prop(cbk, "use_selected_to_active", text="") def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False # No animation. - 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) + scene = context.scene + cscene = scene.cycles + cbk = scene.render.bake + rd = scene.render - 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="") + layout.active = cbk.use_selected_to_active + col = layout.column() - if not part.active_texture: - layout.template_ID(part, "active_texture", new="texture.new") + col.prop(cbk, "use_cage", text="Cage") + if cbk.use_cage: + col.prop(cbk, "cage_extrusion", text="Extrusion") + col.prop(cbk, "cage_object", text="Cage Object") else: - slot = part.texture_slots[part.active_texture_index] - layout.template_ID(slot, "texture", new="texture.new") + col.prop(cbk, "cage_extrusion", text="Ray Distance") -class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel): - bl_label = "Bake" +class CYCLES_RENDER_PT_bake_output(CyclesButtonsPanel, Panel): + bl_label = "Output" bl_context = "render" - bl_options = {'DEFAULT_CLOSED'} + bl_parent_id = "CYCLES_RENDER_PT_bake" COMPAT_ENGINES = {'CYCLES'} def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False # No animation. scene = context.scene cscene = scene.cycles cbk = scene.render.bake + rd = scene.render - layout.operator("object.bake", icon='RENDER_STILL').type = cscene.bake_type - - col = layout.column() - col.prop(cscene, "bake_type") - - col = layout.column() - - 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="") - - 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) - - 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") - - 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() - - split = layout.split() - - col = split.column() - col.prop(cbk, "margin") - col.prop(cbk, "use_clear") + if rd.use_bake_multires: + layout.prop(rd, "bake_margin") + layout.prop(rd, "use_bake_clear", text="Clear Image") - 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="") + if rd.bake_type == 'DISPLACEMENT': + col.prop(rd, "use_bake_lores_mesh") else: - sub.prop(cbk, "cage_extrusion", text="Ray Distance") + + layout.prop(cbk, "margin") + layout.prop(cbk, "use_clear", text="Clear Image") class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel): @@ -1613,7 +1917,7 @@ class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel): col = layout.column() - col.label('CPU Flags:') + col.label(text="CPU Flags:") row = col.row(align=True) row.prop(cscene, "debug_use_cpu_sse2", toggle=True) row.prop(cscene, "debug_use_cpu_sse3", toggle=True) @@ -1626,14 +1930,14 @@ class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel): col.separator() col = layout.column() - col.label('CUDA Flags:') + col.label(text="CUDA Flags:") col.prop(cscene, "debug_use_cuda_adaptive_compile") col.prop(cscene, "debug_use_cuda_split_kernel") col.separator() col = layout.column() - col.label('OpenCL Flags:') + col.label(text='OpenCL Flags:') col.prop(cscene, "debug_opencl_device_type", text="Device") col.prop(cscene, "debug_use_opencl_debug", text="Debug") col.prop(cscene, "debug_opencl_mem_limit") @@ -1644,48 +1948,54 @@ 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_RENDER_PT_simplify(CyclesButtonsPanel, Panel): + bl_label = "Simplify" + bl_context = "render" + bl_options = {'DEFAULT_CLOSED'} + 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_RENDER_PT_simplify_viewport(CyclesButtonsPanel, Panel): + bl_label = "Viewport" + bl_context = "render" + bl_parent_id = "CYCLES_RENDER_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 + layout.use_property_decorate = False - 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" - bl_context = "scene" + 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") + col.prop(rd, "use_simplify_smoke_highres") + +class CYCLES_RENDER_PT_simplify_render(CyclesButtonsPanel, Panel): + bl_label = "Render" + bl_context = "render" + bl_parent_id = "CYCLES_RENDER_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 + layout.use_property_decorate = False scene = context.scene rd = scene.render @@ -1693,80 +2003,79 @@ 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() - col.prop(cscene, "use_camera_cull") - row = col.row() - row.active = cscene.use_camera_cull - row.prop(cscene, "camera_cull_margin") +class CYCLES_RENDER_PT_simplify_culling(CyclesButtonsPanel, Panel): + bl_label = "Culling" + bl_context = "render" + bl_parent_id = "CYCLES_RENDER_PT_simplify" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'CYCLES'} - col = split.column() - col.prop(cscene, "use_distance_cull") - row = col.row() - row.active = cscene.use_distance_cull - row.prop(cscene, "distance_cull_margin", text="Distance") + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False - split = layout.split() - col = split.column() - col.prop(cscene, "ao_bounces") + scene = context.scene + rd = scene.render + cscene = scene.cycles - col = split.column() - col.prop(cscene, "ao_bounces_render") + layout.active = rd.use_simplify + + col = layout.column() + col.prop(cscene, "use_camera_cull") + sub = col.column() + sub.active = cscene.use_camera_cull + sub.prop(cscene, "camera_cull_margin") + + col = layout.column() + col.prop(cscene, "use_distance_cull") + sub = col.column() + sub.active = cscene.use_distance_cull + sub.prop(cscene, "distance_cull_margin", text="Distance") def draw_device(self, context): scene = context.scene layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False - if scene.render.engine == 'CYCLES': + if context.engine == 'CYCLES': from . import engine cscene = scene.cycles - layout.prop(cscene, "feature_set") + col = layout.column() + col.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="") + scene = context.scene + col = layout.column() + col.active = show_device_active(context) + col.prop(cscene, "device") + + from . import engine if engine.with_osl() and use_cpu(context): - layout.prop(cscene, "shading_system") + col.prop(cscene, "shading_system") 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(): @@ -1774,49 +2083,17 @@ def get_panels(): 'DATA_PT_area', 'DATA_PT_camera_dof', 'DATA_PT_falloff_curve', - 'DATA_PT_lamp', + 'DATA_PT_light', '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', + 'NODE_DATA_PT_light', + 'NODE_DATA_PT_spot', + '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' + 'RENDER_PT_simplify', } panels = [] @@ -1829,27 +2106,54 @@ def get_panels(): classes = ( - CYCLES_MT_sampling_presets, - CYCLES_MT_integrator_presets, + CYCLES_PT_sampling_presets, + CYCLES_PT_integrator_presets, CYCLES_RENDER_PT_sampling, - CYCLES_RENDER_PT_geometry, + CYCLES_RENDER_PT_sampling_sub_samples, + CYCLES_RENDER_PT_sampling_advanced, CYCLES_RENDER_PT_light_paths, + CYCLES_RENDER_PT_light_paths_max_bounces, + CYCLES_RENDER_PT_light_paths_clamping, + CYCLES_RENDER_PT_light_paths_caustics, + CYCLES_RENDER_PT_volumes, + CYCLES_RENDER_PT_subdivision, + CYCLES_RENDER_PT_hair, + CYCLES_RENDER_PT_simplify, + CYCLES_RENDER_PT_simplify_viewport, + CYCLES_RENDER_PT_simplify_render, + CYCLES_RENDER_PT_simplify_culling, CYCLES_RENDER_PT_motion_blur, + CYCLES_RENDER_PT_motion_blur_curve, CYCLES_RENDER_PT_film, + CYCLES_RENDER_PT_film_pixel_filter, + CYCLES_RENDER_PT_film_transparency, CYCLES_RENDER_PT_performance, - CYCLES_RENDER_PT_layer_options, - CYCLES_RENDER_PT_layer_passes, - CYCLES_RENDER_PT_views, + 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_override, + CYCLES_RENDER_PT_passes, + CYCLES_RENDER_PT_passes_data, + CYCLES_RENDER_PT_passes_light, + CYCLES_RENDER_PT_passes_crypto, + CYCLES_RENDER_PT_passes_debug, 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, - CYCLES_LAMP_PT_preview, - CYCLES_LAMP_PT_lamp, - CYCLES_LAMP_PT_nodes, - CYCLES_LAMP_PT_spot, + CYCLES_OBJECT_PT_cycles_settings_ray_visibility, + CYCLES_OBJECT_PT_cycles_settings_performance, + CYCLES_LIGHT_PT_preview, + CYCLES_LIGHT_PT_light, + CYCLES_LIGHT_PT_nodes, + CYCLES_LIGHT_PT_spot, CYCLES_WORLD_PT_preview, CYCLES_WORLD_PT_surface, CYCLES_WORLD_PT_volume, @@ -1857,28 +2161,36 @@ 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_bake_influence, + CYCLES_RENDER_PT_bake_selected_to_active, + CYCLES_RENDER_PT_bake_output, CYCLES_RENDER_PT_debug, - CYCLES_PARTICLE_PT_curve_settings, - CYCLES_SCENE_PT_simplify, + node_panel(CYCLES_MATERIAL_PT_settings), + node_panel(CYCLES_MATERIAL_PT_settings_surface), + node_panel(CYCLES_MATERIAL_PT_settings_volume), + node_panel(CYCLES_WORLD_PT_ray_visibility), + node_panel(CYCLES_WORLD_PT_settings), + node_panel(CYCLES_WORLD_PT_settings_surface), + node_panel(CYCLES_WORLD_PT_settings_volume), + node_panel(CYCLES_LIGHT_PT_light), + node_panel(CYCLES_LIGHT_PT_spot), ) 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(): @@ -1891,7 +2203,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(): |