Skip to content
Snippets Groups Projects
ui.py 142 KiB
Newer Older
  • Learn to ignore specific revisions
  • 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?
    
    from bl_operators.presets import AddPresetBase
    
    from bpy.utils import register_class, unregister_class
    
    from bpy.types import (
    
        Operator,
        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')
        except:
            pass
    del properties_output
    
    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')
        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
    
    
    # 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
    
    class WORLD_MT_POV_presets(bpy.types.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():
    
    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
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        if idblock and bpy.context.scene.texture_context == 'OTHER':
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            return idblock
    
    
        # idblock = bpy.context.active_object.active_material
    
        idblock = bpy.context.scene.view_layers[
            "View Layer"
        ].objects.active.active_material
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        if idblock:
            return idblock
    
    
        idblock = context.world
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        if idblock:
            return idblock
    
        idblock = context.light
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        if idblock:
            return idblock
    
        if context.particle_system:
            idblock = context.particle_system.settings
    
        return idblock
    
    
        idblock = context.line_style
        if idblock:
            return idblock
    
    
    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)
    
    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
    
    
        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
    
    
        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
    
    
        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
    
        bl_options = properties_data_mesh.DATA_PT_customdata.bl_options
    
        draw = properties_data_mesh.DATA_PT_customdata.draw
    
    
    
    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(bpy.types.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
    
            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",