Merge branch 'blender2.7'
[blender.git] / intern / cycles / blender / addon / ui.py
index afd13b3..542f02f 100644 (file)
 import bpy
 from bpy_extras.node_utils import find_node_input
 from bl_operators.presets import PresetMenu
-import _cycles
 
-from bpy.types import (
-    Panel,
-    Operator,
-)
+from bpy.types import Panel
 
 
 class CYCLES_PT_sampling_presets(PresetMenu):
@@ -54,8 +50,18 @@ class CyclesButtonsPanel:
         return context.engine in cls.COMPAT_ENGINES
 
 
+class CyclesNodeButtonsPanel:
+    bl_space_type = "NODE_EDITOR"
+    bl_region_type = "UI"
+    COMPAT_ENGINES = {'CYCLES'}
+
+    @classmethod
+    def poll(cls, context):
+        return context.engine in cls.COMPAT_ENGINES
+
+
 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):
@@ -92,7 +98,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):
@@ -234,6 +240,12 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
             col.prop(cscene, "sample_all_lights_direct")
             col.prop(cscene, "sample_all_lights_indirect")
 
+        for view_layer in scene.view_layers:
+            if view_layer.samples > 0:
+                layout.separator()
+                layout.row().prop(cscene, "use_layer_samples")
+                break
+
 
 class CYCLES_RENDER_PT_sampling_total(CyclesButtonsPanel, Panel):
     bl_label = "Total Samples"
@@ -620,6 +632,8 @@ class CYCLES_RENDER_PT_performance_acceleration_structure(CyclesButtonsPanel, Pa
     bl_parent_id = "CYCLES_RENDER_PT_performance"
 
     def draw(self, context):
+        import _cycles
+
         layout = self.layout
         layout.use_property_split = True
         layout.use_property_decorate = False
@@ -710,6 +724,22 @@ class CYCLES_RENDER_PT_filter(CyclesButtonsPanel, Panel):
             col.active = rd.use_freestyle
 
 
+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 = "view_layer"
@@ -901,6 +931,8 @@ class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel):
         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")
 
@@ -1243,27 +1275,6 @@ class CYCLES_OBJECT_PT_cycles_settings_performance(CyclesButtonsPanel, Panel):
         col.prop(cob, "use_distance_cull")
 
 
-class CYCLES_OT_use_shading_nodes(Operator):
-    """Enable nodes on a material, world or light"""
-    bl_idname = "cycles.use_shading_nodes"
-    bl_label = "Use Nodes"
-
-    @classmethod
-    def poll(cls, context):
-        return (getattr(context, "material", False) or getattr(context, "world", False) or
-                getattr(context, "light", False))
-
-    def execute(self, context):
-        if context.material:
-            context.material.use_nodes = True
-        elif context.world:
-            context.world.use_nodes = True
-        elif context.light:
-            context.light.use_nodes = True
-
-        return {'FINISHED'}
-
-
 def panel_node_draw(layout, id_data, output_type, input_name):
     if not id_data.use_nodes:
         layout.operator("cycles.use_shading_nodes", icon='NODETREE')
@@ -1668,31 +1679,29 @@ class CYCLES_MATERIAL_PT_settings(CyclesButtonsPanel, Panel):
     def poll(cls, context):
         return context.material and CyclesButtonsPanel.poll(context)
 
-    def draw(self, context):
+    @staticmethod
+    def draw_shared(self, mat):
         layout = self.layout
         layout.use_property_split = True
         layout.use_property_decorate = False
 
-        mat = context.material
-
         layout.prop(mat, "pass_index")
 
+    def draw(self, context):
+        self.draw_shared(self, context.material)
+
 
 class CYCLES_MATERIAL_PT_settings_surface(CyclesButtonsPanel, Panel):
     bl_label = "Surface"
     bl_parent_id = "CYCLES_MATERIAL_PT_settings"
     bl_context = "material"
 
-    @classmethod
-    def poll(cls, context):
-        return context.material and CyclesButtonsPanel.poll(context)
-
-    def draw(self, context):
+    @staticmethod
+    def draw_shared(self, mat):
         layout = self.layout
         layout.use_property_split = True
         layout.use_property_decorate = False
 
-        mat = context.material
         cmat = mat.cycles
 
         col = layout.column()
@@ -1700,22 +1709,21 @@ class CYCLES_MATERIAL_PT_settings_surface(CyclesButtonsPanel, Panel):
         col.prop(cmat, "use_transparent_shadow")
         col.prop(cmat, "displacement_method", text="Displacement Method")
 
+    def draw(self, context):
+        self.draw_shared(self, context.material)
+
 
 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):
-        return context.material and CyclesButtonsPanel.poll(context)
-
-    def draw(self, context):
+    @staticmethod
+    def draw_shared(self, context, mat):
         layout = self.layout
         layout.use_property_split = True
         layout.use_property_decorate = False
 
-        mat = context.material
         cmat = mat.cycles
 
         col = layout.column()
@@ -1725,6 +1733,9 @@ class CYCLES_MATERIAL_PT_settings_volume(CyclesButtonsPanel, Panel):
         col.prop(cmat, "volume_interpolation", text="Interpolation")
         col.prop(cmat, "homogeneous_volume", text="Homogeneous")
 
+    def draw(self, context):
+        self.draw_shared(self, context, context.material)
+
 
 class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel):
     bl_label = "Bake"
@@ -1742,76 +1753,140 @@ class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel):
         cbk = scene.render.bake
         rd = scene.render
 
-        col = layout.column()
-        col.prop(rd, "use_bake_multires")
         if rd.use_bake_multires:
-            col.prop(rd, "bake_type")
+            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")
 
-            col = layout.column()
-            col.prop(rd, "bake_margin")
-            col.prop(rd, "use_bake_clear")
 
-            if rd.bake_type == 'DISPLACEMENT':
-                col.prop(rd, "use_bake_lores_mesh")
+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):
+        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
 
-            col.operator("object.bake_image", icon='RENDER_STILL')
+    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
+
+        col = layout.column()
+
+        if cscene.bake_type == 'NORMAL':
+            col.prop(cbk, "normal_space", text="Space")
+
+            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")
+
+        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)
+
+            flow = col.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=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_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):
+        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.
+
+        scene = context.scene
+        cscene = scene.cycles
+        cbk = scene.render.bake
+        rd = scene.render
+
+        layout.active = cbk.use_selected_to_active
+        col = layout.column()
+
+        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:
-            col.prop(cscene, "bake_type")
-
-            col = layout.column()
-
-            if cscene.bake_type == 'NORMAL':
-                col.prop(cbk, "normal_space", text="Space")
-
-                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")
-
-            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.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)
-
-            layout.separator()
-
-            col = layout.column()
-            col.prop(cbk, "margin")
-            col.prop(cbk, "use_clear", text="Clear Image")
+            col.prop(cbk, "cage_extrusion", text="Ray Distance")
 
-            col.separator()
 
-            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="Cage Object")
-            else:
-                sub.prop(cbk, "cage_extrusion", text="Ray Distance")
+class CYCLES_RENDER_PT_bake_output(CyclesButtonsPanel, Panel):
+    bl_label = "Output"
+    bl_context = "render"
+    bl_parent_id = "CYCLES_RENDER_PT_bake"
+    COMPAT_ENGINES = {'CYCLES'}
 
-            layout.separator()
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+        layout.use_property_decorate = False  # No animation.
 
-            layout.operator("object.bake", icon='RENDER_STILL').type = cscene.bake_type
+        scene = context.scene
+        cscene = scene.cycles
+        cbk = scene.render.bake
+        rd = scene.render
+
+        if rd.use_bake_multires:
+            layout.prop(rd, "bake_margin")
+            layout.prop(rd, "use_bake_clear", text="Clear Image")
+
+            if rd.bake_type == 'DISPLACEMENT':
+                col.prop(rd, "use_bake_lores_mesh")
+        else:
+
+            layout.prop(cbk, "margin")
+            layout.prop(cbk, "use_clear", text="Clear Image")
 
 
 class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel):
@@ -1852,8 +1927,7 @@ class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel):
         col.separator()
 
         col = layout.column()
-        col.label(text="OpenCL Flags:")
-        col.prop(cscene, "debug_opencl_kernel_type", text="Kernel")
+        col.label(text='OpenCL Flags:')
         col.prop(cscene, "debug_opencl_device_type", text="Device")
         col.prop(cscene, "debug_opencl_kernel_single_program", text="Single Program")
         col.prop(cscene, "debug_use_opencl_debug", text="Debug")
@@ -1901,7 +1975,7 @@ class CYCLES_RENDER_PT_simplify_viewport(CyclesButtonsPanel, Panel):
         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"
@@ -1959,6 +2033,43 @@ class CYCLES_RENDER_PT_simplify_culling(CyclesButtonsPanel, Panel):
         sub.prop(cscene, "distance_cull_margin", text="Distance")
 
 
+class CYCLES_NODE_PT_settings(CyclesNodeButtonsPanel, Panel):
+    bl_label = "Settings"
+    bl_category = "Node"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    @classmethod
+    def poll(cls, context):
+        snode = context.space_data
+        return CyclesNodeButtonsPanel.poll(context) and \
+               snode.tree_type == 'ShaderNodeTree' and snode.id and \
+               snode.id.bl_rna.identifier == 'Material'
+
+    def draw(self, context):
+        material = context.space_data.id
+        CYCLES_MATERIAL_PT_settings.draw_shared(self, material)
+
+
+class CYCLES_NODE_PT_settings_surface(CyclesNodeButtonsPanel, Panel):
+    bl_label = "Surface"
+    bl_category = "Node"
+    bl_parent_id = "CYCLES_NODE_PT_settings"
+
+    def draw(self, context):
+        material = context.space_data.id
+        CYCLES_MATERIAL_PT_settings_surface.draw_shared(self, material)
+
+
+class CYCLES_NODE_PT_settings_volume(CyclesNodeButtonsPanel, Panel):
+    bl_label = "Volume"
+    bl_category = "Node"
+    bl_parent_id = "CYCLES_NODE_PT_settings"
+
+    def draw(self, context):
+        material = context.space_data.id
+        CYCLES_MATERIAL_PT_settings_volume.draw_shared(self, context, material)
+
+
 def draw_device(self, context):
     scene = context.scene
     layout = self.layout
@@ -2049,6 +2160,7 @@ classes = (
     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,
@@ -2064,7 +2176,6 @@ classes = (
     CYCLES_OBJECT_PT_cycles_settings,
     CYCLES_OBJECT_PT_cycles_settings_ray_visibility,
     CYCLES_OBJECT_PT_cycles_settings_performance,
-    CYCLES_OT_use_shading_nodes,
     CYCLES_LIGHT_PT_preview,
     CYCLES_LIGHT_PT_light,
     CYCLES_LIGHT_PT_nodes,
@@ -2086,7 +2197,13 @@ classes = (
     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_NODE_PT_settings,
+    CYCLES_NODE_PT_settings_surface,
+    CYCLES_NODE_PT_settings_volume,
 )