Skip to content
Snippets Groups Projects
ui.py 161 KiB
Newer Older
Luca Bonavita's avatar
Luca Bonavita committed
# ##### BEGIN GPL LICENSE BLOCK #####
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software Foundation,
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####

# <pep8 compliant>
Maurice Raybaud's avatar
Maurice Raybaud committed
"""User interface for the POV tools"""
Luca Bonavita's avatar
Luca Bonavita committed
import bpy
import sys  # really import here and in render.py?
import os  # really import here and in render.py?
import addon_utils
from time import sleep
from bpy.app.handlers import persistent
from bl_operators.presets import AddPresetBase
from bpy.utils import register_class, unregister_class
from bpy.types import (
    UIList,
    Panel,
    Brush,
    Material,
    Light,
    World,
    ParticleSettings,
    FreestyleLineStyle,
)

# Example of wrapping every class 'as is'
from bl_ui import properties_output
for member in dir(properties_output):
    subclass = getattr(properties_output, member)
    try:
        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
    except:
        pass
del properties_output

from bl_ui import properties_freestyle
for member in dir(properties_freestyle):
    subclass = getattr(properties_freestyle, member)
    try:
        if not (subclass.bl_space_type == 'PROPERTIES'
            and subclass.bl_context == "render"):
            subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
            #subclass.bl_parent_id = "RENDER_PT_POV_filter"
    except:
        pass
del properties_freestyle

from bl_ui import properties_view_layer
for member in dir(properties_view_layer):
    subclass = getattr(properties_view_layer, member)
    try:
        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
    except:
        pass
del properties_view_layer
Luca Bonavita's avatar
Luca Bonavita committed

# Use some of the existing buttons.
from bl_ui import properties_render

# DEPRECATED#properties_render.RENDER_PT_render.COMPAT_ENGINES.add('POVRAY_RENDER')
# DEPRECATED#properties_render.RENDER_PT_dimensions.COMPAT_ENGINES.add('POVRAY_RENDER')
# properties_render.RENDER_PT_antialiasing.COMPAT_ENGINES.add('POVRAY_RENDER')
# TORECREATE##DEPRECATED#properties_render.RENDER_PT_shading.COMPAT_ENGINES.add('POVRAY_RENDER')
# DEPRECATED#properties_render.RENDER_PT_output.COMPAT_ENGINES.add('POVRAY_RENDER')
Luca Bonavita's avatar
Luca Bonavita committed
del properties_render

Luca Bonavita's avatar
Luca Bonavita committed
# Use only a subset of the world panels
from bl_ui import properties_world

# TORECREATE##DEPRECATED#properties_world.WORLD_PT_preview.COMPAT_ENGINES.add('POVRAY_RENDER')
properties_world.WORLD_PT_context_world.COMPAT_ENGINES.add('POVRAY_RENDER')
# TORECREATE##DEPRECATED#properties_world.WORLD_PT_world.COMPAT_ENGINES.add('POVRAY_RENDER')
# TORECREATE##DEPRECATED#properties_world.WORLD_PT_mist.COMPAT_ENGINES.add('POVRAY_RENDER')
Luca Bonavita's avatar
Luca Bonavita committed
del properties_world

# Example of wrapping every class 'as is'
from bl_ui import properties_texture
from bl_ui.properties_texture import context_tex_datablock
from bl_ui.properties_texture import texture_filter_common
Luca Bonavita's avatar
Luca Bonavita committed
for member in dir(properties_texture):
    subclass = getattr(properties_texture, member)
    try:
        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
Luca Bonavita's avatar
Luca Bonavita committed
    except:
        pass
del properties_texture

# Physics Main wrapping every class 'as is'
from bl_ui import properties_physics_common
for member in dir(properties_physics_common):
    subclass = getattr(properties_physics_common, member)
    try:
        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
    except:
        pass
del properties_physics_common

# Physics Rigid Bodies wrapping every class 'as is'
from bl_ui import properties_physics_rigidbody
for member in dir(properties_physics_rigidbody):
    subclass = getattr(properties_physics_rigidbody, member)
    try:
        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
    except:
        pass
del properties_physics_rigidbody

# Physics Rigid Body Constraint wrapping every class 'as is'
from bl_ui import properties_physics_rigidbody_constraint
for member in dir(properties_physics_rigidbody_constraint):
    subclass = getattr(properties_physics_rigidbody_constraint, member)
    try:
        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
    except:
        pass
del properties_physics_rigidbody_constraint

# Physics Smoke wrapping every class 'as is'
from bl_ui import properties_physics_fluid
for member in dir(properties_physics_fluid):
    subclass = getattr(properties_physics_fluid, member)
    try:
        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
    except:
        pass
del properties_physics_fluid

# Physics softbody wrapping every class 'as is'
from bl_ui import properties_physics_softbody
for member in dir(properties_physics_softbody):
    subclass = getattr(properties_physics_softbody, member)
    try:
        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
    except:
        pass
del properties_physics_softbody

# Physics Fluid wrapping every class 'as is'
from bl_ui import properties_physics_fluid
for member in dir(properties_physics_fluid):
    subclass = getattr(properties_physics_fluid, member)
    try:
        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
    except:
        pass
del properties_physics_fluid

# Physics Field wrapping every class 'as is'
from bl_ui import properties_physics_field
for member in dir(properties_physics_field):
    subclass = getattr(properties_physics_field, member)
    try:
        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
    except:
        pass
del properties_physics_field

# Physics Cloth wrapping every class 'as is'
from bl_ui import properties_physics_cloth
for member in dir(properties_physics_cloth):
    subclass = getattr(properties_physics_cloth, member)
    try:
        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
    except:
        pass
del properties_physics_cloth

# Physics Dynamic Paint wrapping every class 'as is'
from bl_ui import properties_physics_dynamicpaint
for member in dir(properties_physics_dynamicpaint):
    subclass = getattr(properties_physics_dynamicpaint, member)
    try:
        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
    except:
        pass
del properties_physics_dynamicpaint

# Example of wrapping every class 'as is'
from bl_ui import properties_data_modifier
for member in dir(properties_data_modifier):
    subclass = getattr(properties_data_modifier, member)
    try:
        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
    except:
        pass
del properties_data_modifier

# Example of wrapping every class 'as is' except some
from bl_ui import properties_material
for member in dir(properties_material):
    subclass = getattr(properties_material, member)
Maurice Raybaud's avatar
Maurice Raybaud committed
        # mat=bpy.context.active_object.active_material
Maurice Raybaud's avatar
Maurice Raybaud committed
        # if (mat and mat.pov.type == "SURFACE"
        # and not (mat.pov.material_use_nodes or mat.use_nodes)):
Maurice Raybaud's avatar
Maurice Raybaud committed
        # and (engine in cls.COMPAT_ENGINES)) if subclasses were sorted
        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
from bl_ui import properties_data_camera
Luca Bonavita's avatar
Luca Bonavita committed
for member in dir(properties_data_camera):
    subclass = getattr(properties_data_camera, member)
    try:
        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
Luca Bonavita's avatar
Luca Bonavita committed
    except:
        pass
del properties_data_camera

from bl_ui import properties_particle as properties_particle

for member in dir(
    properties_particle
):  # add all "particle" panels from blender
    subclass = getattr(properties_particle, member)
    try:
        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
    except:
        pass
del properties_particle

############# POV-Centric WORSPACE #############
@persistent
def povCentricWorkspace(dummy):
    """Set up a POV centric Workspace if addon was activated and saved as default renderer

    This would bring a ’_RestrictData’ error because UI needs to be fully loaded before
    workspace changes so registering this function in bpy.app.handlers is needed.
    By default handlers are freed when loading new files, but here we want the handler
    to stay running across multiple files as part of this add-on. That is why the the
    bpy.app.handlers.persistent decorator is used (@persistent) above.
    """

    wsp = bpy.data.workspaces.get('Scripting')
    context = bpy.context
    if wsp is not None and context.scene.render.engine == 'POVRAY_RENDER':
        new_wsp = bpy.ops.workspace.duplicate({'workspace': wsp})
        bpy.data.workspaces['Scripting.001'].name='POV'
        # Already done it would seem, but explicitly make this workspaces the active one
        context.window.workspace = bpy.data.workspaces['POV']
        pov_screen = bpy.data.workspaces['POV'].screens[0]
        pov_workspace = pov_screen.areas


        override = bpy.context.copy()

        for area in pov_workspace:
            if area.type == 'VIEW_3D':
                for region in [r for r in area.regions if r.type == 'WINDOW']:
                    for space in area.spaces:
                        if space.type == 'VIEW_3D':
                            #override['screen'] = pov_screen
                            override['area'] = area
                            override['region']= region
                            #bpy.data.workspaces['POV'].screens[0].areas[6].spaces[0].width = 333 # Read only, how do we set ?
                            #This has a glitch:
                            #bpy.ops.screen.area_move(override, x=(area.x + area.width), y=(area.y + 5), delta=100)
                            #bpy.ops.screen.area_move(override, x=(area.x + 5), y=area.y, delta=-100)

                            bpy.ops.screen.space_type_set_or_cycle(override, space_type = 'TEXT_EDITOR')
                            space.show_region_ui = True
                            #bpy.ops.screen.region_scale(override)
                            #bpy.ops.screen.region_scale()
                            break

            elif area.type == 'CONSOLE':
                for region in [r for r in area.regions if r.type == 'WINDOW']:
                    for space in area.spaces:
                        if space.type == 'CONSOLE':
                            #override['screen'] = pov_screen
                            override['area'] = area
                            override['region']= region
                            bpy.ops.screen.space_type_set_or_cycle(override, space_type = 'INFO')

                            break
            elif area.type == 'INFO':
                for region in [r for r in area.regions if r.type == 'WINDOW']:
                    for space in area.spaces:
                        if space.type == 'INFO':
                            #override['screen'] = pov_screen
                            override['area'] = area
                            override['region']= region
                            bpy.ops.screen.space_type_set_or_cycle(override, space_type = 'CONSOLE')

                            break

            elif area.type == 'TEXT_EDITOR':
                for region in [r for r in area.regions if r.type == 'WINDOW']:
                    for space in area.spaces:
                        if space.type == 'TEXT_EDITOR':
                            #override['screen'] = pov_screen
                            override['area'] = area
                            override['region']= region
                            #bpy.ops.screen.space_type_set_or_cycle(space_type='VIEW_3D')
                            #space.type = 'VIEW_3D'
                            bpy.ops.screen.space_type_set_or_cycle(override, space_type = 'VIEW_3D')

                            #bpy.ops.screen.area_join(override, cursor=(area.x, area.y + area.height))

                            break


            if area.type == 'VIEW_3D':
                for region in [r for r in area.regions if r.type == 'WINDOW']:
                    for space in area.spaces:
                        if space.type == 'VIEW_3D':
                            #override['screen'] = pov_screen
                            override['area'] = area
                            override['region']= region
                            bpy.ops.screen.region_quadview(override)
                            space.region_3d.view_perspective = 'CAMERA'
                            #bpy.ops.screen.space_type_set_or_cycle(override, space_type = 'TEXT_EDITOR')
                            #bpy.ops.screen.region_quadview(override)




        bpy.data.workspaces.update()
        # Already outliners but invert both types
        pov_workspace[1].spaces[0].display_mode = 'LIBRARIES'
        pov_workspace[3].spaces[0].display_mode = 'VIEW_LAYER'

        '''
        for window in bpy.context.window_manager.windows:
            for area in [a for a in window.screen.areas if a.type == 'VIEW_3D']:
                for region in [r for r in area.regions if r.type == 'WINDOW']:
                    context_override = {
                        'window': window,
                        'screen': window.screen,
                        'area': area,
                        'region': region,
                        'space_data': area.spaces.active,
                        'scene': bpy.context.scene
                        }
                    bpy.ops.view3d.camera_to_view(context_override)
        '''


    else:
        print("default 'Scripting' workspace needed for POV centric Workspace")







class WORLD_MT_POV_presets(Menu):
    bl_label = "World Presets"
    preset_subdir = "pov/world"
    preset_operator = "script.execute_preset"
    draw = bpy.types.Menu.draw_preset


class WORLD_OT_POV_add_preset(AddPresetBase, Operator):
    """Add a World Preset"""
    bl_idname = "object.world_preset_add"
    bl_label = "Add World Preset"
    preset_menu = "WORLD_MT_POV_presets"

    # variable used for all preset values
    preset_defines = ["scene = bpy.context.scene"]

    # properties to store in the preset
    preset_values = [
        "scene.world.use_sky_blend",
        "scene.world.horizon_color",
        "scene.world.zenith_color",
        "scene.world.ambient_color",
        "scene.world.mist_settings.use_mist",
        "scene.world.mist_settings.intensity",
        "scene.world.mist_settings.depth",
        "scene.world.mist_settings.start",
        "scene.pov.media_enable",
        "scene.pov.media_scattering_type",
        "scene.pov.media_samples",
        "scene.pov.media_diffusion_scale",
        "scene.pov.media_diffusion_color",
        "scene.pov.media_absorption_scale",
        "scene.pov.media_absorption_color",
        "scene.pov.media_eccentricity",

    # where to store the preset
    preset_subdir = "pov/world"
def check_material(mat):
    if mat is not None:
        if mat.use_nodes:
            if (
                not mat.node_tree
            ):  # FORMERLY : #mat.active_node_material is not None:
                return True
            return False
        return True
    return False

Maurice Raybaud's avatar
Maurice Raybaud committed
    """Test if a material uses nodes"""
    if (mat is not None) and (not mat.use_nodes):
        return True
    return False
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Test if Add mesh extra objects addon is activated
Maurice Raybaud's avatar
Maurice Raybaud committed
    This addon is currently used to generate the proxy for POV parametric
    surface which is almost the same priciple as its Math xyz surface
    """
    if "add_mesh_extra_objects" in bpy.context.preferences.addons.keys():
def check_render_freestyle_svg():
    """Test if Freestyle SVG Exporter addon is activated

    This addon is currently used to generate the SVG lines file
    when Freestyle is enabled alongside POV
    """
    if "render_freestyle_svg" in bpy.context.preferences.addons.keys():
        return True
    return False
Maurice Raybaud's avatar
Maurice Raybaud committed
    """POV can be installed with some include files.
Maurice Raybaud's avatar
Maurice Raybaud committed
    Get their path as defined in user preferences or registry keys for
    the user to be able to invoke them."""
    addon_prefs = bpy.context.preferences.addons[__package__].preferences
    # Use the system preference if its set.
    pov_documents = addon_prefs.docpath_povray
    if pov_documents:
        if os.path.exists(pov_documents):
            return pov_documents
        else:
            print(
                "User Preferences path to povray documents %r NOT FOUND, checking $PATH"
                % pov_documents
            )

    # Windows Only
    if sys.platform[:3] == "win":
        import winreg
            win_reg_key = winreg.OpenKey(
                winreg.HKEY_CURRENT_USER, "Software\\POV-Ray\\v3.7\\Windows"
            )
            win_docpath = winreg.QueryValueEx(win_reg_key, "DocPath")[0]
            pov_documents = os.path.join(win_docpath, "Insert Menu")
            if os.path.exists(pov_documents):
                return pov_documents
        except FileNotFoundError:
    # search the path all os's
    pov_documents_default = "include"

    os_path_ls = os.getenv("PATH").split(':') + [""]

    for dir_name in os_path_ls:
        pov_documents = os.path.join(dir_name, pov_documents_default)
        if os.path.exists(pov_documents):
            return pov_documents
    return ""
Maurice Raybaud's avatar
Maurice Raybaud committed
def pov_context_tex_datablock(context):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Texture context type recreated as deprecated in blender 2.8"""
    idblock = context.brush
    if idblock and context.scene.texture_context == 'OTHER':
Maurice Raybaud's avatar
Maurice Raybaud committed
        return idblock

    # idblock = bpy.context.active_object.active_material
    idblock = context.view_layer.objects.active.active_material
    if idblock and context.scene.texture_context == 'MATERIAL':
Maurice Raybaud's avatar
Maurice Raybaud committed
        return idblock

    idblock = context.scene.world
    if idblock and context.scene.texture_context == 'WORLD':
Maurice Raybaud's avatar
Maurice Raybaud committed
        return idblock
    idblock = context.light
    if idblock and context.scene.texture_context == 'LIGHT':
Maurice Raybaud's avatar
Maurice Raybaud committed
        return idblock

    if context.particle_system and context.scene.texture_context == 'PARTICLES':
Maurice Raybaud's avatar
Maurice Raybaud committed
        idblock = context.particle_system.settings

    return idblock

    idblock = context.line_style
    if idblock and context.scene.texture_context == 'LINESTYLE':

class RenderButtonsPanel:
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define buttons from the render tab of
    properties window."""
Luca Bonavita's avatar
Luca Bonavita committed
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "render"
    # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here

    @classmethod
    def poll(cls, context):
Luca Bonavita's avatar
Luca Bonavita committed
        rd = context.scene.render
        return rd.engine in cls.COMPAT_ENGINES
Luca Bonavita's avatar
Luca Bonavita committed


class ModifierButtonsPanel:
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define buttons from the modifier tab of
    properties window."""
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "modifier"
    # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here

    @classmethod
    def poll(cls, context):
        mods = context.object.modifiers
        rd = context.scene.render
        return mods and (rd.engine in cls.COMPAT_ENGINES)

class MaterialButtonsPanel:
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define buttons from the material tab of
    properties window."""
Maurice Raybaud's avatar
Maurice Raybaud committed
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "material"
    # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here

    @classmethod
    def poll(cls, context):
        mat = context.material
        rd = context.scene.render
        return mat and (rd.engine in cls.COMPAT_ENGINES)
class TextureButtonsPanel:
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define buttons from the texture tab of
    properties window."""
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "texture"
    # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here

    @classmethod
    def poll(cls, context):
        tex = context.texture
        rd = context.scene.render
        return tex and (rd.engine in cls.COMPAT_ENGINES)
Maurice Raybaud's avatar
Maurice Raybaud committed

# class TextureTypePanel(TextureButtonsPanel):

# @classmethod
# def poll(cls, context):
# tex = context.texture
# engine = context.scene.render.engine
# return tex and ((tex.type == cls.tex_type and not tex.use_nodes) and (engine in cls.COMPAT_ENGINES))
class ObjectButtonsPanel:
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define buttons from the object tab of
    properties window."""
Maurice Raybaud's avatar
Maurice Raybaud committed
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"
    # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here

    @classmethod
    def poll(cls, context):
        obj = context.object
        rd = context.scene.render
        return obj and (rd.engine in cls.COMPAT_ENGINES)

class CameraDataButtonsPanel:
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define buttons from the camera data tab of
    properties window."""
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "data"
    # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here

    @classmethod
    def poll(cls, context):
        cam = context.camera
        rd = context.scene.render
        return cam and (rd.engine in cls.COMPAT_ENGINES)

class WorldButtonsPanel:
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define buttons from the world tab of
    properties window."""
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "world"
    # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
    @classmethod
    def poll(cls, context):
        wld = context.world
        rd = context.scene.render
        return wld and (rd.engine in cls.COMPAT_ENGINES)
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define buttons from the side tab of
    text window."""
    bl_space_type = 'TEXT_EDITOR'
    bl_region_type = 'UI'
    # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here

    @classmethod
    def poll(cls, context):
        text = context.space_data
        rd = context.scene.render
        return text and (rd.engine in cls.COMPAT_ENGINES)
from bl_ui import properties_data_mesh
# These panels are kept
properties_data_mesh.DATA_PT_custom_props_mesh.COMPAT_ENGINES.add(
    'POVRAY_RENDER'
)
properties_data_mesh.DATA_PT_context_mesh.COMPAT_ENGINES.add('POVRAY_RENDER')
## make some native panels contextual to some object variable
## by recreating custom panels inheriting their properties
class PovDataButtonsPanel(properties_data_mesh.MeshButtonsPanel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define buttons from the edit data tab of
    properties window."""
    COMPAT_ENGINES = {'POVRAY_RENDER'}
    POV_OBJECT_TYPES = {
        'PLANE',
        'BOX',
        'SPHERE',
        'CYLINDER',
        'CONE',
        'TORUS',
        'BLOB',
        'ISOSURFACE',
        'SUPERELLIPSOID',
        'SUPERTORUS',
        'HEIGHT_FIELD',
        'PARAMETRIC',
        'POLYCIRCLE',
    }
    @classmethod
    def poll(cls, context):
        engine = context.scene.render.engine
        obj = context.object
        # We use our parent class poll func too, avoids to re-define too much things...
        return (
            super(PovDataButtonsPanel, cls).poll(context)
            and obj
            and obj.pov.object_as not in cls.POV_OBJECT_TYPES
        )
# We cannot inherit from RNA classes (like e.g. properties_data_mesh.DATA_PT_vertex_groups).
# Complex py/bpy/rna interactions (with metaclass and all) simply do not allow it to work.
# So we simply have to explicitly copy here the interesting bits. ;)
class DATA_PT_POV_normals(PovDataButtonsPanel, Panel):
    bl_label = properties_data_mesh.DATA_PT_normals.bl_label
    draw = properties_data_mesh.DATA_PT_normals.draw
class DATA_PT_POV_texture_space(PovDataButtonsPanel, Panel):
    bl_label = properties_data_mesh.DATA_PT_texture_space.bl_label
    bl_options = properties_data_mesh.DATA_PT_texture_space.bl_options
    draw = properties_data_mesh.DATA_PT_texture_space.draw
class DATA_PT_POV_vertex_groups(PovDataButtonsPanel, Panel):
    bl_label = properties_data_mesh.DATA_PT_vertex_groups.bl_label
    draw = properties_data_mesh.DATA_PT_vertex_groups.draw


class DATA_PT_POV_shape_keys(PovDataButtonsPanel, Panel):
    bl_label = properties_data_mesh.DATA_PT_shape_keys.bl_label

Campbell Barton's avatar
Campbell Barton committed
    draw = properties_data_mesh.DATA_PT_shape_keys.draw


class DATA_PT_POV_uv_texture(PovDataButtonsPanel, Panel):
    bl_label = properties_data_mesh.DATA_PT_uv_texture.bl_label
Campbell Barton's avatar
Campbell Barton committed

    draw = properties_data_mesh.DATA_PT_uv_texture.draw


class DATA_PT_POV_vertex_colors(PovDataButtonsPanel, Panel):
    bl_label = properties_data_mesh.DATA_PT_vertex_colors.bl_label
Campbell Barton's avatar
Campbell Barton committed

    draw = properties_data_mesh.DATA_PT_vertex_colors.draw


class DATA_PT_POV_customdata(PovDataButtonsPanel, Panel):
    bl_label = properties_data_mesh.DATA_PT_customdata.bl_label
Campbell Barton's avatar
Campbell Barton committed
    bl_options = properties_data_mesh.DATA_PT_customdata.bl_options
    draw = properties_data_mesh.DATA_PT_customdata.draw

Campbell Barton's avatar
Campbell Barton committed

del properties_data_mesh


################################################################################
# from bl_ui import properties_data_light
# for member in dir(properties_data_light):
# subclass = getattr(properties_data_light, member)
# try:
# subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
# except:
# pass
# del properties_data_light
#########################LIGHTS################################
from bl_ui import properties_data_light
properties_data_light.DATA_PT_custom_props_light.COMPAT_ENGINES.add(
    'POVRAY_RENDER'
)
properties_data_light.DATA_PT_context_light.COMPAT_ENGINES.add('POVRAY_RENDER')
## make some native panels contextual to some object variable
## by recreating custom panels inheriting their properties
class PovLampButtonsPanel(properties_data_light.DataButtonsPanel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define buttons from the light data tab of
    properties window."""
    COMPAT_ENGINES = {'POVRAY_RENDER'}
    POV_OBJECT_TYPES = {'RAINBOW'}
    @classmethod
    def poll(cls, context):
        engine = context.scene.render.engine
        obj = context.object
        # We use our parent class poll func too, avoids to re-define too much things...
        return (
            super(PovLampButtonsPanel, cls).poll(context)
            and obj
            and obj.pov.object_as not in cls.POV_OBJECT_TYPES
        )
# We cannot inherit from RNA classes (like e.g. properties_data_mesh.DATA_PT_vertex_groups).
# Complex py/bpy/rna interactions (with metaclass and all) simply do not allow it to work.
# So we simply have to explicitly copy here the interesting bits. ;)
class LIGHT_PT_POV_preview(PovLampButtonsPanel, Panel):
    bl_label = properties_data_light.DATA_PT_preview.bl_label
    draw = properties_data_light.DATA_PT_preview.draw
class LIGHT_PT_POV_light(PovLampButtonsPanel, Panel):
    bl_label = properties_data_light.DATA_PT_light.bl_label
    draw = properties_data_light.DATA_PT_light.draw
class LIGHT_MT_POV_presets(Menu):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define preset menu for pov lights."""

    bl_label = "Lamp Presets"
    preset_subdir = "pov/light"
    preset_operator = "script.execute_preset"
    draw = bpy.types.Menu.draw_preset


class LIGHT_OT_POV_add_preset(AddPresetBase, Operator):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define pov world buttons."""

    '''Add a Light Preset'''
    bl_idname = "object.light_preset_add"
    bl_label = "Add Light Preset"
    preset_menu = "LIGHT_MT_POV_presets"

    # variable used for all preset values
    preset_defines = ["lightdata = bpy.context.object.data"]

    # properties to store in the preset
    preset_values = ["lightdata.type", "lightdata.color"]

    # where to store the preset
    preset_subdir = "pov/light"
# Draw into the existing light panel
def light_panel_func(self, context):
    layout = self.layout

    row = layout.row(align=True)
    row.menu(LIGHT_MT_POV_presets.__name__, text=LIGHT_MT_POV_presets.bl_label)
    row.operator(LIGHT_OT_POV_add_preset.bl_idname, text="", icon='ADD')
    row.operator(
        LIGHT_OT_POV_add_preset.bl_idname, text="", icon='REMOVE'
    ).remove_active = True

'''#TORECREATE##DEPRECATED#
class LIGHT_PT_POV_sunsky(PovLampButtonsPanel, Panel):
    bl_label = properties_data_light.DATA_PT_sunsky.bl_label
    @classmethod
    def poll(cls, context):
        lamp = context.light
        engine = context.scene.render.engine
        return (lamp and lamp.type == 'SUN') and (engine in cls.COMPAT_ENGINES)

    draw = properties_data_light.DATA_PT_sunsky.draw
class LIGHT_PT_POV_shadow(PovLampButtonsPanel, Panel):
    COMPAT_ENGINES = {'POVRAY_RENDER'}
    @classmethod
    def poll(cls, context):
        lamp = context.lamp
        engine = context.scene.render.engine
        return lamp and (engine in cls.COMPAT_ENGINES)
    def draw(self, context):
        layout = self.layout

        lamp = context.lamp
        layout.row().prop(lamp, "shadow_method", expand=True)
        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.prop(lamp, "use_square")
        col.prop(lamp, "show_cone")

        col = split.column()

        col.active = (
            lamp.shadow_method != 'BUFFER_SHADOW'
            or lamp.shadow_buffer_type != 'DEEP'
        )
        col.prop(lamp, "use_halo")
        sub = col.column(align=True)
        sub.active = lamp.use_halo
        sub.prop(lamp, "halo_intensity", text="Intensity")
        if lamp.shadow_method == 'BUFFER_SHADOW':
            sub.prop(lamp, "halo_step", text="Step")
        if lamp.shadow_method == 'NOSHADOW' and lamp.type == 'AREA':
            split = layout.split()

            col = split.column()
            col.label(text="Form factor sampling:")

            sub = col.row(align=True)

            if lamp.shape == 'SQUARE':
                sub.prop(lamp, "shadow_ray_samples_x", text="Samples")
            elif lamp.shape == 'RECTANGLE':
                sub.prop(lamp.pov, "shadow_ray_samples_x", text="Samples X")
                sub.prop(lamp.pov, "shadow_ray_samples_y", text="Samples Y")

        if lamp.shadow_method != 'NOSHADOW':
            split = layout.split()

            col = split.column()
            col.prop(lamp, "shadow_color", text="")

            col = split.column()
            col.prop(lamp, "use_shadow_layer", text="This Layer Only")
            col.prop(lamp, "use_only_shadow")

        if lamp.shadow_method == 'RAY_SHADOW':
            split = layout.split()

            col = split.column()
            col.label(text="Sampling:")

            if lamp.type in {'POINT', 'SUN', 'SPOT'}:
                sub = col.row()

                sub.prop(lamp, "shadow_ray_samples", text="Samples")
                sub.prop(lamp, "shadow_soft_size", text="Soft Size")

            elif lamp.type == 'AREA':
                sub = col.row(align=True)

                if lamp.shape == 'SQUARE':
                    sub.prop(lamp, "shadow_ray_samples_x", text="Samples")
                elif lamp.shape == 'RECTANGLE':
                    sub.prop(lamp, "shadow_ray_samples_x", text="Samples X")
                    sub.prop(lamp, "shadow_ray_samples_y", text="Samples Y")
        if lamp.shadow_method == 'NOSHADOW' and lamp.type == 'AREA':
            split = layout.split()

            col = split.column()
            col.label(text="Form factor sampling:")

            sub = col.row(align=True)

            if lamp.shape == 'SQUARE':
                sub.prop(lamp, "shadow_ray_samples_x", text="Samples")
            elif lamp.shape == 'RECTANGLE':
                sub.prop(lamp, "shadow_ray_samples_x", text="Samples X")
                sub.prop(lamp, "shadow_ray_samples_y", text="Samples Y")

        if lamp.shadow_method != 'NOSHADOW':
            split = layout.split()

            col = split.column()
            col.prop(lamp, "shadow_color", text="")

            col = split.column()
            col.prop(lamp, "use_shadow_layer", text="This Layer Only")
            col.prop(lamp, "use_only_shadow")

        if lamp.shadow_method == 'RAY_SHADOW':
            split = layout.split()

            col = split.column()
            col.label(text="Sampling:")

            if lamp.type in {'POINT', 'SUN', 'SPOT'}:
                sub = col.row()

                sub.prop(lamp, "shadow_ray_samples", text="Samples")
                sub.prop(lamp, "shadow_soft_size", text="Soft Size")

            elif lamp.type == 'AREA':
                sub = col.row(align=True)

                if lamp.shape == 'SQUARE':
                    sub.prop(lamp, "shadow_ray_samples_x", text="Samples")
                elif lamp.shape == 'RECTANGLE':
                    sub.prop(lamp, "shadow_ray_samples_x", text="Samples X")
                    sub.prop(lamp, "shadow_ray_samples_y", text="Samples Y")

            col.row().prop(lamp, "shadow_ray_sample_method", expand=True)

            if lamp.shadow_ray_sample_method == 'ADAPTIVE_QMC':
                layout.prop(lamp, "shadow_adaptive_threshold", text="Threshold")

            if lamp.type == 'AREA' and lamp.shadow_ray_sample_method == 'CONSTANT_JITTERED':
                row = layout.row()
                row.prop(lamp, "use_umbra")
                row.prop(lamp, "use_dither")
                row.prop(lamp, "use_jitter")

        elif lamp.shadow_method == 'BUFFER_SHADOW':
            col = layout.column()
            col.label(text="Buffer Type:")
            col.row().prop(lamp, "shadow_buffer_type", expand=True)

            if lamp.shadow_buffer_type in {'REGULAR', 'HALFWAY', 'DEEP'}:
                split = layout.split()

                col = split.column()
                col.label(text="Filter Type:")
                col.prop(lamp, "shadow_filter_type", text="")
                sub = col.column(align=True)
                sub.prop(lamp, "shadow_buffer_soft", text="Soft")
                sub.prop(lamp, "shadow_buffer_bias", text="Bias")

                col = split.column()
                col.label(text="Sample Buffers:")
                col.prop(lamp, "shadow_sample_buffers", text="")
                sub = col.column(align=True)
                sub.prop(lamp, "shadow_buffer_size", text="Size")
                sub.prop(lamp, "shadow_buffer_samples", text="Samples")
                if lamp.shadow_buffer_type == 'DEEP':
                    col.prop(lamp, "compression_threshold")

            elif lamp.shadow_buffer_type == 'IRREGULAR':
                layout.prop(lamp, "shadow_buffer_bias", text="Bias")

            split = layout.split()

            col = split.column()
            col.prop(lamp, "use_auto_clip_start", text="Autoclip Start")
            sub = col.column()
            sub.active = not lamp.use_auto_clip_start
            sub.prop(lamp, "shadow_buffer_clip_start", text="Clip Start")

            col = split.column()
            col.prop(lamp, "use_auto_clip_end", text="Autoclip End")
            sub = col.column()
            sub.active = not lamp.use_auto_clip_end
            sub.prop(lamp, "shadow_buffer_clip_end", text=" Clip End")
'''

class LIGHT_PT_POV_area(PovLampButtonsPanel, Panel):
    bl_label = properties_data_light.DATA_PT_area.bl_label

    @classmethod
    def poll(cls, context):
        lamp = context.light
        engine = context.scene.render.engine
        return (lamp and lamp.type == 'AREA') and (engine in cls.COMPAT_ENGINES)
    draw = properties_data_light.DATA_PT_area.draw
class LIGHT_PT_POV_spot(PovLampButtonsPanel, Panel):
    bl_label = properties_data_light.DATA_PT_spot.bl_label

    @classmethod
    def poll(cls, context):
        lamp = context.light
        engine = context.scene.render.engine
Campbell Barton's avatar
Campbell Barton committed
        return (lamp and lamp.type == 'SPOT') and (engine in cls.COMPAT_ENGINES)
    draw = properties_data_light.DATA_PT_spot.draw
class LIGHT_PT_POV_falloff_curve(PovLampButtonsPanel, Panel):
    bl_label = properties_data_light.DATA_PT_falloff_curve.bl_label
    bl_options = properties_data_light.DATA_PT_falloff_curve.bl_options
    @classmethod
    def poll(cls, context):
        lamp = context.light
        engine = context.scene.render.engine

        return (
            lamp
            and lamp.type in {'POINT', 'SPOT'}
            and lamp.falloff_type == 'CUSTOM_CURVE'
        ) and (engine in cls.COMPAT_ENGINES)

    draw = properties_data_light.DATA_PT_falloff_curve.draw
class OBJECT_PT_POV_rainbow(PovLampButtonsPanel, Panel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define buttons from the rainbow panel of
    properties window. inheriting lamp buttons panel class"""
    bl_label = "POV-Ray Rainbow"
    COMPAT_ENGINES = {'POVRAY_RENDER'}
    # bl_options = {'HIDE_HEADER'}
    @classmethod
    def poll(cls, context):
        engine = context.scene.render.engine
        obj = context.object
        return (
            obj
            and obj.pov.object_as == 'RAINBOW'
            and (engine in cls.COMPAT_ENGINES)
        )

    def draw(self, context):
        layout = self.layout

        obj = context.object
        col = layout.column()

        if obj.pov.object_as == 'RAINBOW':
            if obj.pov.unlock_parameters == False:
                col.prop(
                    obj.pov,
                    "unlock_parameters",
                    text="Exported parameters below",
                    icon='LOCKED',
                )
                col.label(
                    text="Rainbow projection angle: " + str(obj.data.spot_size)
                )
                col.label(text="Rainbow width: " + str(obj.data.spot_blend))
                col.label(
                    text="Rainbow distance: "
                    + str(obj.data.shadow_buffer_clip_start)
                )
                col.label(text="Rainbow arc angle: " + str(obj.pov.arc_angle))
                col.label(
                    text="Rainbow falloff angle: " + str(obj.pov.falloff_angle)
                )
                col.prop(
                    obj.pov,
                    "unlock_parameters",
                    text="Edit exported parameters",
                    icon='UNLOCKED',
                )
                col.label(text="3D view proxy may get out of synch")
                col.active = obj.pov.unlock_parameters

                layout.operator(
                    "pov.cone_update", text="Update", icon="MESH_CONE"
                )
                # col.label(text="Parameters:")
                col.prop(obj.data, "spot_size", text="Rainbow Projection Angle")
                col.prop(obj.data, "spot_blend", text="Rainbow width")
                col.prop(
                    obj.data,
                    "shadow_buffer_clip_start",
                    text="Visibility distance",
                )
                col.prop(obj.pov, "arc_angle")
                col.prop(obj.pov, "falloff_angle")
del properties_data_light
###############################################################################
class WORLD_PT_POV_world(WorldButtonsPanel, Panel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define pov world buttons."""
    bl_label = "World"
    COMPAT_ENGINES = {'POVRAY_RENDER'}

    def draw(self, context):
        layout = self.layout


        row = layout.row(align=True)
        row.menu(
            WORLD_MT_POV_presets.__name__, text=WORLD_MT_POV_presets.bl_label
        )
        row.operator(WORLD_OT_POV_add_preset.bl_idname, text="", icon='ADD')
        row.operator(
            WORLD_OT_POV_add_preset.bl_idname, text="", icon='REMOVE'
        ).remove_active = True
        row.prop(world, "use_sky_paper")
        row.prop(world, "use_sky_blend")
        row.prop(world, "use_sky_real")

        row = layout.row()
        row.column().prop(world, "horizon_color")
        col = row.column()
        col.prop(world, "zenith_color")
        col.active = world.use_sky_blend
        row.column().prop(world, "ambient_color")

        # row = layout.row()
        # row.prop(world, "exposure") #Re-implement later as a light multiplier
        # row.prop(world, "color_range")

class WORLD_PT_POV_mist(WorldButtonsPanel, Panel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define pov mist buttons."""

    bl_label = "Mist"
    bl_options = {'DEFAULT_CLOSED'}
    COMPAT_ENGINES = {'POVRAY_RENDER'}

    def draw_header(self, context):
        world = context.world

        self.layout.prop(world.mist_settings, "use_mist", text="")

    def draw(self, context):
        layout = self.layout

        world = context.world

        layout.active = world.mist_settings.use_mist

        split = layout.split()

        col = split.column()
        col.prop(world.mist_settings, "intensity")
        col.prop(world.mist_settings, "start")

        col = split.column()
        col.prop(world.mist_settings, "depth")
        col.prop(world.mist_settings, "height")

        layout.prop(world.mist_settings, "falloff")
class RENDER_PT_POV_export_settings(RenderButtonsPanel, Panel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define pov ini settingss buttons."""
    bl_options = {'DEFAULT_CLOSED'}
    bl_label = "Auto Start"
    COMPAT_ENGINES = {'POVRAY_RENDER'}
    def draw_header(self, context):
        scene = context.scene
        if scene.pov.tempfiles_enable:
            self.layout.prop(
                scene.pov, "tempfiles_enable", text="", icon='AUTO'
            )
            self.layout.prop(
                scene.pov, "tempfiles_enable", text="", icon='CONSOLE'
            )
Maurice Raybaud's avatar
Maurice Raybaud committed
    def draw(self, context):
Maurice Raybaud's avatar
Maurice Raybaud committed
        layout = self.layout

        scene = context.scene
        layout.active = scene.pov.max_trace_level != 0
        split = layout.split()
        col = split.column()
        col.label(text="Command line switches:")
        col.prop(scene.pov, "command_line_switches", text="")
        split = layout.split()
        #layout.active = not scene.pov.tempfiles_enable
        if not scene.pov.tempfiles_enable:
            split.prop(scene.pov, "deletefiles_enable", text="Delete files")
            split.prop(scene.pov, "pov_editor", text="POV Editor")
            col = layout.column()
            col.prop(scene.pov, "scene_name", text="Name")
            col.prop(scene.pov, "scene_path", text="Path to files")
            # col.prop(scene.pov, "scene_path", text="Path to POV-file")
            # col.prop(scene.pov, "renderimage_path", text="Path to image")
            split = layout.split()
            split.prop(scene.pov, "indentation_character", text="Indent")
            if scene.pov.indentation_character == 'SPACE':
                split.prop(scene.pov, "indentation_spaces", text="Spaces")
            row = layout.row()
            row.prop(scene.pov, "comments_enable", text="Comments")
            row.prop(scene.pov, "list_lf_enable", text="Line breaks in lists")
class RENDER_PT_POV_render_settings(RenderButtonsPanel, Panel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define pov render settings buttons."""

    bl_label = "Global Settings"
    bl_options = {'DEFAULT_CLOSED'}
Maurice Raybaud's avatar
Maurice Raybaud committed
    COMPAT_ENGINES = {'POVRAY_RENDER'}

    def draw_header(self, context):
        scene = context.scene
        if scene.pov.global_settings_advanced:
            self.layout.prop(
                scene.pov, "global_settings_advanced", text="", icon='SETTINGS'
            )
            self.layout.prop(
                scene.pov,
                "global_settings_advanced",
                text="",
                icon='PREFERENCES',
            )

Maurice Raybaud's avatar
Maurice Raybaud committed
    def draw(self, context):
        layout = self.layout

        scene = context.scene
        rd = context.scene.render
        # layout.active = (scene.pov.max_trace_level != 0)
        if sys.platform[:3] != "win":
            layout.prop(
                scene.pov, "sdl_window_enable", text="POV-Ray SDL Window"
            )
Thomas Dinges's avatar
Thomas Dinges committed
        col = layout.column()
        col.label(text="Main Path Tracing:")
        col.prop(scene.pov, "max_trace_level", text="Ray Depth")
Maurice Raybaud's avatar
Maurice Raybaud committed
        align = True
        layout.active = scene.pov.global_settings_advanced
Maurice Raybaud's avatar
Maurice Raybaud committed
        # Deprecated (autodetected in pov3.8):
        # layout.prop(scene.pov, "charset")
        row = layout.row(align=align)
        row.prop(scene.pov, "adc_bailout")
        row = layout.row(align=align)
        row.prop(scene.pov, "ambient_light")
        row = layout.row(align=align)
        row.prop(scene.pov, "irid_wavelength")
        row = layout.row(align=align)
        row.prop(scene.pov, "max_intersections")
        row = layout.row(align=align)
        row.prop(scene.pov, "number_of_waves")
        row = layout.row(align=align)
        row.prop(scene.pov, "noise_generator")
        split = layout.split()
        split.label(text="Shading:")
        split = layout.split()
        row = split.row(align=align)
        row.prop(scene.pov, "use_shadows")
Maurice Raybaud's avatar
Maurice Raybaud committed
        row.prop(scene.pov, "alpha_mode")

class RENDER_PT_POV_photons(RenderButtonsPanel, Panel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define pov photons buttons."""

    bl_options = {'DEFAULT_CLOSED'}
    # self.layout.label(icon='SETTINGS')
    def draw_header(self, context):
        scene = context.scene
        if scene.pov.photon_enable:
            self.layout.prop(
                scene.pov, "photon_enable", text="", icon='PMARKER_ACT'
            )
            self.layout.prop(
                scene.pov, "photon_enable", text="", icon='PMARKER'
            )

    def draw(self, context):
        scene = context.scene
        layout = self.layout
        layout.active = scene.pov.photon_enable
        col = layout.column()
        # col.label(text="Global Photons:")
        col.prop(scene.pov, "photon_max_trace_level", text="Photon Depth")
        col = split.column()
        col.prop(scene.pov, "photon_spacing", text="Spacing")
        col.prop(scene.pov, "photon_gather_min")
        col = split.column()
        col.prop(scene.pov, "photon_adc_bailout", text="Photon ADC")
        col.prop(scene.pov, "photon_gather_max")
        box.label(text='Photon Map File:')
        row.prop(scene.pov, "photon_map_file_save_load", expand=True)
        if scene.pov.photon_map_file_save_load in {'save'}:
            box.prop(scene.pov, "photon_map_dir")
            box.prop(scene.pov, "photon_map_filename")
        if scene.pov.photon_map_file_save_load in {'load'}:
            box.prop(scene.pov, "photon_map_file")
class RENDER_PT_POV_antialias(RenderButtonsPanel, Panel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define pov antialiasing buttons."""

    bl_label = "Anti-Aliasing"
    bl_options = {'DEFAULT_CLOSED'}
    COMPAT_ENGINES = {'POVRAY_RENDER'}

    def draw_header(self, context):
        prefs = bpy.context.preferences.addons[__package__].preferences
        scene = context.scene
        if (
            prefs.branch_feature_set_povray != 'uberpov'
            and scene.pov.antialias_method == '2'
        ):
            self.layout.prop(
                scene.pov, "antialias_enable", text="", icon='ERROR'
            )
        elif scene.pov.antialias_enable:
            self.layout.prop(
                scene.pov, "antialias_enable", text="", icon='ANTIALIASED'
            )
            self.layout.prop(
                scene.pov, "antialias_enable", text="", icon='ALIASED'
            )

    def draw(self, context):
        prefs = bpy.context.preferences.addons[__package__].preferences
        layout = self.layout
        scene = context.scene
Thomas Dinges's avatar
Thomas Dinges committed
        row = layout.row()
        row.prop(scene.pov, "antialias_method", text="")
        if (
            prefs.branch_feature_set_povray != 'uberpov'
            and scene.pov.antialias_method == '2'
        ):
            col = layout.column()
            col.alignment = 'CENTER'
            col.label(text="Stochastic Anti Aliasing is")
            col.label(text="Only Available with UberPOV")
            col.label(text="Feature Set in User Preferences.")
Campbell Barton's avatar
Campbell Barton committed
            col.label(text="Using Type 2 (recursive) instead")
            row.prop(scene.pov, "jitter_enable", text="Jitter")

            split = layout.split()
            col = split.column()
            col.prop(scene.pov, "antialias_depth", text="AA Depth")
            sub = split.column()
            sub.prop(scene.pov, "jitter_amount", text="Jitter Amount")
            if scene.pov.jitter_enable:
                sub.enabled = True
            else:
                sub.enabled = False

            row = layout.row()
            row.prop(scene.pov, "antialias_threshold", text="AA Threshold")
            row.prop(scene.pov, "antialias_gamma", text="AA Gamma")
            if prefs.branch_feature_set_povray == 'uberpov':
                row.prop(
                    scene.pov, "antialias_confidence", text="AA Confidence"
                )
                if scene.pov.antialias_method == '2':
                    row.enabled = True
                else:
                    row.enabled = False
class RENDER_PT_POV_radiosity(RenderButtonsPanel, Panel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define pov radiosity buttons."""

    bl_label = "Diffuse Radiosity"
    bl_options = {'DEFAULT_CLOSED'}
    COMPAT_ENGINES = {'POVRAY_RENDER'}
Luca Bonavita's avatar
Luca Bonavita committed
    def draw_header(self, context):
        scene = context.scene
        if scene.pov.radio_enable:
            self.layout.prop(
                scene.pov,
                "radio_enable",
                text="",
                icon='OUTLINER_OB_LIGHTPROBE',
            )
            self.layout.prop(
                scene.pov, "radio_enable", text="", icon='LIGHTPROBE_CUBEMAP'
            )
Luca Bonavita's avatar
Luca Bonavita committed

    def draw(self, context):
        layout = self.layout

        scene = context.scene

Luca Bonavita's avatar
Luca Bonavita committed

        split = layout.split()

        col = split.column()
        col.prop(scene.pov, "radio_count", text="Rays")
        col.prop(scene.pov, "radio_recursion_limit", text="Recursions")
        split.prop(scene.pov, "radio_error_bound", text="Error Bound")
Luca Bonavita's avatar
Luca Bonavita committed

        layout.prop(scene.pov, "radio_display_advanced")
Luca Bonavita's avatar
Luca Bonavita committed

Luca Bonavita's avatar
Luca Bonavita committed
            split = layout.split()

            col = split.column()
            col.prop(scene.pov, "radio_adc_bailout", slider=True)
Campbell Barton's avatar
Campbell Barton committed
            col.prop(scene.pov, "radio_minimum_reuse", text="Min Reuse")
            col.prop(scene.pov, "radio_gray_threshold", slider=True)
            col.prop(scene.pov, "radio_pretrace_start", slider=True)
            col.prop(scene.pov, "radio_low_error_factor", slider=True)
Luca Bonavita's avatar
Luca Bonavita committed
            col = split.column()
            col.prop(scene.pov, "radio_maximum_reuse", text="Max Reuse")
            col.prop(scene.pov, "radio_nearest_count")
            col.prop(scene.pov, "radio_pretrace_end", slider=True)
Luca Bonavita's avatar
Luca Bonavita committed

Luca Bonavita's avatar
Luca Bonavita committed
            col.label(text="Estimation Influence:")
            col.prop(scene.pov, "radio_always_sample")
            col.prop(scene.pov, "radio_media")
            col.prop(scene.pov, "radio_subsurface")
Luca Bonavita's avatar
Luca Bonavita committed

class POV_RADIOSITY_MT_presets(Menu):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define pov radiosity presets menu."""

    bl_label = "Radiosity Presets"
    preset_subdir = "pov/radiosity"
    preset_operator = "script.execute_preset"
    draw = bpy.types.Menu.draw_preset


class RENDER_OT_POV_radiosity_add_preset(AddPresetBase, Operator):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define pov radiosity add presets button."""

    '''Add a Radiosity Preset'''
    bl_idname = "scene.radiosity_preset_add"
    bl_label = "Add Radiosity Preset"
    preset_menu = "POV_RADIOSITY_MT_presets"

    # variable used for all preset values
    preset_defines = ["scene = bpy.context.scene"]

    # properties to store in the preset
    preset_values = [
Campbell Barton's avatar
Campbell Barton committed
        "scene.pov.radio_display_advanced",
        "scene.pov.radio_adc_bailout",
        "scene.pov.radio_always_sample",
        "scene.pov.radio_brightness",
        "scene.pov.radio_count",
        "scene.pov.radio_error_bound",
        "scene.pov.radio_gray_threshold",
        "scene.pov.radio_low_error_factor",
        "scene.pov.radio_media",
        "scene.pov.radio_subsurface",
        "scene.pov.radio_minimum_reuse",
        "scene.pov.radio_maximum_reuse",
        "scene.pov.radio_nearest_count",
        "scene.pov.radio_normal",
        "scene.pov.radio_recursion_limit",
        "scene.pov.radio_pretrace_start",
Campbell Barton's avatar
Campbell Barton committed
        "scene.pov.radio_pretrace_end",

    # where to store the preset
    preset_subdir = "pov/radiosity"


# Draw into an existing panel
def rad_panel_func(self, context):
    layout = self.layout

    row = layout.row(align=True)
    row.menu(
        POV_RADIOSITY_MT_presets.__name__,
        text=POV_RADIOSITY_MT_presets.bl_label,
    )
    row.operator(
        RENDER_OT_POV_radiosity_add_preset.bl_idname, text="", icon='ADD'
    )
    row.operator(
        RENDER_OT_POV_radiosity_add_preset.bl_idname, text="", icon='REMOVE'
    ).remove_active = True

class RENDER_PT_POV_media(WorldButtonsPanel, Panel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define a pov global atmospheric media buttons."""

    bl_label = "Atmosphere Media"
    COMPAT_ENGINES = {'POVRAY_RENDER'}

    def draw_header(self, context):
        scene = context.scene

        self.layout.prop(scene.pov, "media_enable", text="")

    def draw(self, context):
        layout = self.layout

        scene = context.scene

        col = layout.column()
        col.prop(scene.pov, "media_scattering_type", text="")
        col = layout.column()
        col.prop(scene.pov, "media_samples", text="Samples")
Campbell Barton's avatar
Campbell Barton committed
        split = layout.split()
        col = split.column(align=True)
        col.label(text="Scattering:")
        col.prop(scene.pov, "media_diffusion_scale")
        col.prop(scene.pov, "media_diffusion_color", text="")
        col = split.column(align=True)
        col.label(text="Absorption:")
Campbell Barton's avatar
Campbell Barton committed
        col.prop(scene.pov, "media_absorption_scale")
        col.prop(scene.pov, "media_absorption_color", text="")
        if scene.pov.media_scattering_type == '5':
            col = layout.column()
            col.prop(scene.pov, "media_eccentricity", text="Eccentricity")
##class RENDER_PT_povray_baking(RenderButtonsPanel, Panel):
##    bl_label = "Baking"
##    COMPAT_ENGINES = {'POVRAY_RENDER'}
##
##    def draw_header(self, context):
##        scene = context.scene
##
##        self.layout.prop(scene.pov, "baking_enable", text="")
##
##    def draw(self, context):
##        layout = self.layout
##
##        scene = context.scene
##        rd = scene.render
##
class MODIFIERS_PT_POV_modifiers(ModifierButtonsPanel, Panel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define pov modifier buttons. (For booleans)"""

    bl_label = "POV-Ray"
    COMPAT_ENGINES = {'POVRAY_RENDER'}

    # def draw_header(self, context):
    # scene = context.scene
    # self.layout.prop(scene.pov, "boolean_mod", text="")

    def draw(self, context):
        scene = context.scene
        layout = self.layout
        ob = context.object
        mod = ob.modifiers
        col = layout.column()
        # Find Boolean Modifiers for displaying CSG option
        onceCSG = 0
        for mod in ob.modifiers:
            if onceCSG == 0:
                    if mod.type == 'BOOLEAN':
                        col.prop(ob.pov, "boolean_mod")
                        onceCSG = 1

Campbell Barton's avatar
Campbell Barton committed
                    if ob.pov.boolean_mod == "POV":
                        split = layout.split()
                        col = layout.column()
                        # Inside Vector for CSG
                        col.prop(ob.pov, "inside_vector")
class MATERIAL_MT_POV_sss_presets(Menu):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define pov sss preset menu."""

    bl_label = "SSS Presets"
    preset_subdir = "pov/material/sss"
    preset_operator = "script.execute_preset"
    draw = bpy.types.Menu.draw_preset

class MATERIAL_OT_POV_sss_add_preset(AddPresetBase, Operator):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Add an SSS Preset"""
    bl_idname = "material.sss_preset_add"
    bl_label = "Add SSS Preset"
    preset_menu = "MATERIAL_MT_POV_sss_presets"

    # variable used for all preset values
    preset_defines = ["material = bpy.context.material"]

    # properties to store in the preset
    preset_values = [
        "material.pov_subsurface_scattering.radius",
        "material.pov_subsurface_scattering.color",

    # where to store the preset
    preset_subdir = "pov/material/sss"

class MATERIAL_PT_POV_sss(MaterialButtonsPanel, Panel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define pov sss buttons panel."""

    bl_label = "Subsurface Scattering"
    bl_options = {'DEFAULT_CLOSED'}
    COMPAT_ENGINES = {'POVRAY_RENDER'}

    @classmethod
    def poll(cls, context):
        mat = context.material
        engine = context.scene.render.engine
        return (
            check_material(mat)
            and (mat.pov.type in {'SURFACE', 'WIRE'})
            and (engine in cls.COMPAT_ENGINES)
        )
        mat = context.material  # FORMERLY : #active_node_mat(context.material)
        sss = mat.pov_subsurface_scattering

        self.layout.active = not mat.pov.use_shadeless
        self.layout.prop(sss, "use", text="")

    def draw(self, context):
        layout = self.layout
        mat = context.material  # FORMERLY : #active_node_mat(context.material)
        sss = mat.pov_subsurface_scattering

        layout.active = (sss.use) and (not mat.pov.use_shadeless)

        row = layout.row().split()
        sub = row.row(align=True).split(align=True, factor=0.75)
        sub.menu(
            MATERIAL_MT_POV_sss_presets.__name__,
            text=MATERIAL_MT_POV_sss_presets.bl_label,
        )
        sub.operator(
            MATERIAL_OT_POV_sss_add_preset.bl_idname, text="", icon='ADD'
        )
        sub.operator(
            MATERIAL_OT_POV_sss_add_preset.bl_idname, text="", icon='REMOVE'
        ).remove_active = True

        split = layout.split()

        col = split.column()
        col.prop(sss, "ior")
        col.prop(sss, "scale")
        col.prop(sss, "color", text="")
        col.prop(sss, "radius", text="RGB Radius", expand=True)

        col = split.column()
        sub = col.column(align=True)
        sub.label(text="Blend:")
        sub.prop(sss, "color_factor", text="Color")
        sub.prop(sss, "texture_factor", text="Texture")
        sub.label(text="Scattering Weight:")
        sub.prop(sss, "front")
        sub.prop(sss, "back")
        col.separator()
        col.prop(sss, "error_threshold", text="Error")
class MATERIAL_PT_POV_activate_node(MaterialButtonsPanel, Panel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define an activate pov nodes button."""

    bl_label = "Activate Node Settings"
    bl_context = "material"
    bl_options = {'HIDE_HEADER'}
    COMPAT_ENGINES = {'POVRAY_RENDER'}

    @classmethod
    def poll(cls, context):
        engine = context.scene.render.engine
        mat = context.material
        ob = context.object
        return (
            mat
            and mat.pov.type == "SURFACE"
            and (engine in cls.COMPAT_ENGINES)
            and not (mat.pov.material_use_nodes or mat.use_nodes)
        )
    def draw(self, context):
        layout = self.layout
        # layout.operator("pov.material_use_nodes", icon='SOUND')#'NODETREE')
        # the above replaced with a context hook below:
        layout.operator(
            "WM_OT_context_toggle", text="Use POV-Ray Nodes", icon='NODETREE'
        ).data_path = "material.pov.material_use_nodes"

class MATERIAL_PT_POV_active_node(MaterialButtonsPanel, Panel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to show pov active node properties buttons."""

    bl_label = "Active Node Settings"
    bl_context = "material"
    bl_options = {'HIDE_HEADER'}
    COMPAT_ENGINES = {'POVRAY_RENDER'}

    @classmethod
    def poll(cls, context):
        engine = context.scene.render.engine
        mat = context.material
        ob = context.object
        return (
            mat
            and mat.pov.type == "SURFACE"
            and (engine in cls.COMPAT_ENGINES)
            and mat.pov.material_use_nodes
        )

    def draw(self, context):
        layout = self.layout
        mat = context.material
        node_tree = mat.node_tree
        if node_tree:
            node = node_tree.nodes.active
            if mat.use_nodes:
                if node:
                    layout.prop(mat.pov, "material_active_node")
                    if node.bl_idname == "PovrayMaterialNode":
                        layout.context_pointer_set("node", node)
                        if hasattr(node, "draw_buttons_ext"):
                            node.draw_buttons_ext(context, layout)
                        elif hasattr(node, "draw_buttons"):
                            node.draw_buttons(context, layout)
                        value_inputs = [
                            socket
                            for socket in node.inputs
                            if socket.enabled and not socket.is_linked
                        ]
                        if value_inputs:
                            layout.separator()
                            layout.label(text="Inputs:")
                            for socket in value_inputs:
                                row = layout.row()
                                socket.draw(context, row, node, socket.name)
                    else:
                        layout.context_pointer_set("node", node)
                        if hasattr(node, "draw_buttons_ext"):
                            node.draw_buttons_ext(context, layout)
                        elif hasattr(node, "draw_buttons"):
                            node.draw_buttons(context, layout)
                        value_inputs = [
                            socket
                            for socket in node.inputs
                            if socket.enabled and not socket.is_linked
                        ]
                        if value_inputs:
                            layout.separator()
                            layout.label(text="Inputs:")
                            for socket in value_inputs:
                                row = layout.row()
                                socket.draw(context, row, node, socket.name)
                else:
                    layout.label(text="No active nodes!")
class MATERIAL_PT_POV_specular(MaterialButtonsPanel, Panel):
    """Use this class to define standard material specularity (highlights) buttons."""

    bl_label = "Specular"
    COMPAT_ENGINES = {'POVRAY_RENDER'}

    @classmethod
    def poll(cls, context):
        mat = context.material
        engine = context.scene.render.engine
        return (
            check_material(mat)
            and (mat.pov.type in {'SURFACE', 'WIRE'})
            and (engine in cls.COMPAT_ENGINES)
        )
    def draw(self, context):
        layout = self.layout

        mat = context.material.pov

        layout.active = (not mat.use_shadeless)

        split = layout.split()

        col = split.column()
        col.prop(mat, "specular_color", text="")
        col.prop(mat, "specular_intensity", text="Intensity")

        col = split.column()
        col.prop(mat, "specular_shader", text="")
        col.prop(mat, "use_specular_ramp", text="Ramp")

        col = layout.column()
        if mat.specular_shader in {'COOKTORR', 'PHONG'}:
            col.prop(mat, "specular_hardness", text="Hardness")
        elif mat.specular_shader == 'BLINN':
            row = col.row()
            row.prop(mat, "specular_hardness", text="Hardness")
            row.prop(mat, "specular_ior", text="IOR")
        elif mat.specular_shader == 'WARDISO':
            col.prop(mat, "specular_slope", text="Slope")
        elif mat.specular_shader == 'TOON':
            row = col.row()
            row.prop(mat, "specular_toon_size", text="Size")
            row.prop(mat, "specular_toon_smooth", text="Smooth")

        if mat.use_specular_ramp:
            layout.separator()
            layout.template_color_ramp(mat, "specular_ramp", expand=True)
            layout.separator()

            row = layout.row()
            row.prop(mat, "specular_ramp_input", text="Input")
            row.prop(mat, "specular_ramp_blend", text="Blend")

            layout.prop(mat, "specular_ramp_factor", text="Factor")
class MATERIAL_PT_POV_mirror(MaterialButtonsPanel, Panel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define standard material reflectivity (mirror) buttons."""

    bl_label = "Mirror"
    bl_options = {'DEFAULT_CLOSED'}
    bl_idname = "MATERIAL_PT_POV_raytrace_mirror"
    COMPAT_ENGINES = {'POVRAY_RENDER'}
    @classmethod
    def poll(cls, context):
        mat = context.material
        engine = context.scene.render.engine
        return (
            check_material(mat)
            and (mat.pov.type in {'SURFACE', 'WIRE'})
            and (engine in cls.COMPAT_ENGINES)
        )

    def draw_header(self, context):
        mat = context.material
        raym = mat.pov_raytrace_mirror

        self.layout.prop(raym, "use", text="")

    def draw(self, context):
        layout = self.layout

        mat = (
            context.material
        )  # Formerly : #mat = active_node_mat(context.material)
        raym = mat.pov_raytrace_mirror

        layout.active = raym.use

        split = layout.split()
        col = split.column()
        col.prop(raym, "reflect_factor")
        col.prop(raym, "mirror_color", text="")

        col = split.column()
        col.prop(raym, "fresnel")
        sub = col.column()
        sub.active = raym.fresnel > 0.0
        sub.prop(raym, "fresnel_factor", text="Blend")

        split = layout.split()

        col = split.column()
        col.separator()
        col.prop(raym, "depth")
        col.prop(raym, "distance", text="Max Dist")
        col.separator()
        sub = col.split(factor=0.4)
        sub.active = raym.distance > 0.0
        sub.label(text="Fade To:")
        sub.prop(raym, "fade_to", text="")

        col = split.column()
        col.label(text="Gloss:")
        col.prop(raym, "gloss_factor", text="Amount")
        sub = col.column()
        sub.active = raym.gloss_factor < 1.0
        sub.prop(raym, "gloss_threshold", text="Threshold")
        sub.prop(raym, "gloss_samples", text="Noise")
        sub.prop(raym, "gloss_anisotropic", text="Anisotropic")
class MATERIAL_PT_POV_transp(MaterialButtonsPanel, Panel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define pov material transparency (alpha) buttons."""

    bl_label = "Transparency"
    COMPAT_ENGINES = {'POVRAY_RENDER'}

    @classmethod
    def poll(cls, context):
        mat = context.material
        engine = context.scene.render.engine
        return (
            check_material(mat)
            and (mat.pov.type in {'SURFACE', 'WIRE'})
            and (engine in cls.COMPAT_ENGINES)
        )

    def draw_header(self, context):
        mat = context.material

        if simple_material(mat):
            self.layout.prop(mat.pov, "use_transparency", text="")

    def draw(self, context):
        layout = self.layout

        base_mat = context.material
        mat = context.material  # FORMERLY active_node_mat(context.material)
        rayt = mat.pov_raytrace_transparency

        if simple_material(base_mat):
            row = layout.row()
            row.active = mat.pov.use_transparency
            row.prop(mat.pov, "transparency_method", expand=True)

        split = layout.split()
        split.active = base_mat.pov.use_transparency

        col = split.column()
        col.prop(mat.pov, "alpha")
        row = col.row()
        row.active = (base_mat.pov.transparency_method != 'MASK') and (
            not mat.pov.use_shadeless
        )
        row.prop(mat.pov, "specular_alpha", text="Specular")

        col = split.column()
        col.active = not mat.pov.use_shadeless
        col.prop(rayt, "fresnel")
        sub = col.column()
        sub.active = rayt.fresnel > 0.0
        sub.prop(rayt, "fresnel_factor", text="Blend")

        if base_mat.pov.transparency_method == 'RAYTRACE':
            layout.separator()
            split = layout.split()
            split.active = base_mat.pov.use_transparency

            col = split.column()
            col.prop(rayt, "ior")
            col.prop(rayt, "filter")
            col.prop(rayt, "falloff")
            col.prop(rayt, "depth_max")
            col.prop(rayt, "depth")

            col = split.column()
            col.label(text="Gloss:")
            col.prop(rayt, "gloss_factor", text="Amount")
            sub = col.column()
            sub.active = rayt.gloss_factor < 1.0
            sub.prop(rayt, "gloss_threshold", text="Threshold")
            sub.prop(rayt, "gloss_samples", text="Samples")
class MATERIAL_PT_POV_reflection(MaterialButtonsPanel, Panel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define more pov specific reflectivity buttons."""

Maurice Raybaud's avatar
Maurice Raybaud committed
    bl_parent_id = "MATERIAL_PT_POV_raytrace_mirror"
Maurice Raybaud's avatar
Maurice Raybaud committed
    COMPAT_ENGINES = {'POVRAY_RENDER'}

    @classmethod
    def poll(cls, context):
        engine = context.scene.render.engine
        mat = context.material
        ob = context.object
        return (
            mat
            and mat.pov.type == "SURFACE"
            and (engine in cls.COMPAT_ENGINES)
            and not (mat.pov.material_use_nodes or mat.use_nodes)
        )
Maurice Raybaud's avatar
Maurice Raybaud committed
    def draw(self, context):
        layout = self.layout
        mat = context.material
        col = layout.column()
        col.prop(mat.pov, "irid_enable")
        if mat.pov.irid_enable:
Thomas Dinges's avatar
Thomas Dinges committed
            col = layout.column()
            col.prop(mat.pov, "irid_amount", slider=True)
            col.prop(mat.pov, "irid_thickness", slider=True)
Campbell Barton's avatar
Campbell Barton committed
            col.prop(mat.pov, "irid_turbulence", slider=True)
        col2 = col.split().column()
        if not mat.pov_raytrace_mirror.use:
Campbell Barton's avatar
Campbell Barton committed
            col2.label(text="Please Check Mirror settings :")
        col2.active = mat.pov_raytrace_mirror.use
        col2.prop(mat.pov, "mirror_use_IOR")
        if mat.pov.mirror_use_IOR:
            col2.alignment = 'CENTER'
            col2.label(text="The current Raytrace ")
            col2.label(text="Transparency IOR is: " + str(mat.pov.ior))
'''
#group some native Blender (SSS) and POV (Fade)settings under such a parent panel?
class MATERIAL_PT_POV_interior(MaterialButtonsPanel, Panel):
    bl_label = "POV-Ray Interior"
Maurice Raybaud's avatar
Maurice Raybaud committed
    bl_idname = "material.pov_interior"
    #bl_parent_id = "material.absorption"
    COMPAT_ENGINES = {'POVRAY_RENDER'}
    @classmethod
    def poll(cls, context):
        engine = context.scene.render.engine
        mat=context.material
        ob = context.object
        return mat and mat.pov.type == "SURFACE" and (engine in cls.COMPAT_ENGINES) and not (mat.pov.material_use_nodes or mat.use_nodes)
    def draw_header(self, context):
        mat = context.material
Maurice Raybaud's avatar
Maurice Raybaud committed
'''
class MATERIAL_PT_POV_fade_color(MaterialButtonsPanel, Panel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define pov fading (absorption) color buttons."""

    COMPAT_ENGINES = {'POVRAY_RENDER'}
    # bl_parent_id = "material.pov_interior"
    @classmethod
    def poll(cls, context):
        engine = context.scene.render.engine
        mat = context.material
        ob = context.object
        return (
            mat
            and mat.pov.type == "SURFACE"
            and (engine in cls.COMPAT_ENGINES)
            and not (mat.pov.material_use_nodes or mat.use_nodes)
        )
    def draw_header(self, context):
        mat = context.material

        self.layout.prop(mat.pov, "interior_fade_color", text="")
    def draw(self, context):
        layout = self.layout
        mat = context.material
        # layout.active = mat.pov.interior_fade_color
        if mat.pov.interior_fade_color != (0.0, 0.0, 0.0):
            layout.label(text="Raytrace transparency")
            layout.label(text="depth max Limit needs")
            layout.label(text="to be non zero to fade")
class MATERIAL_PT_POV_caustics(MaterialButtonsPanel, Panel):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Use this class to define pov caustics buttons."""

    bl_label = "Caustics"
    COMPAT_ENGINES = {'POVRAY_RENDER'}

    @classmethod
    def poll(cls, context):
        engine = context.scene.render.engine
        mat = context.material
Loading
Loading full blame...