Skip to content
Snippets Groups Projects
__init__.py 86.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • # ##### BEGIN GPL LICENSE BLOCK #####
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #
    #  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 #####
    
    
        "name": "POVRAY-3.7",
    
        "author": "Campbell Barton, Silvio Falcinelli, Maurice Raybaud, "
                  "Constantin Rahn, Bastien Montagne, Leonid Desyatkov",
    
        "blender": (2, 75, 0),
    
        "location": "Render > Engine > POV-Ray 3.7",
    
        "description": "Basic POV-Ray 3.7 integration for blender",
    
        "warning": "this script is RC",
    
        "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
    
                    "Scripts/Render/POV-Ray",
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
    if "bpy" in locals():
    
        import importlib
        importlib.reload(ui)
        importlib.reload(render)
        importlib.reload(update_files)
    
    
    else:
        import bpy
    
        import addon_utils # To use some other addons
    
        import nodeitems_utils #for Nodes
        from nodeitems_utils import NodeCategory, NodeItem #for Nodes
    
        from bpy.types import (
                AddonPreferences,
                PropertyGroup,
    
                )
        from bpy.props import (
                StringProperty,
                BoolProperty,
                IntProperty,
                FloatProperty,
                FloatVectorProperty,
                EnumProperty,
                PointerProperty,
    
                )
        from . import (
                ui,
                render,
                update_files,
                )
    
    def string_strip_hyphen(name):
        return name.replace("-", "")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
    ###############################################################################
    # Scene POV properties.
    ###############################################################################
    
    class RenderPovSettingsScene(PropertyGroup):
    
        # File Options
    
                name="Enable Tempfiles",
    
                description="Enable the OS-Tempfiles. Otherwise set the path where"
                            " to save the files",
    
                default=True)
    
        pov_editor = BoolProperty(
                name="POV-Ray editor",
    
                description="Don't Close POV-Ray editor after rendering (Overriden"
                            " by /EXIT command)",
    
                name="Delete files",
    
                description="Delete files after rendering. "
                            "Doesn't work with the image",
    
                default=True)
    
                name="Scene Name",
    
                description="Name of POV-Ray scene to create. Empty name will use "
                            "the name of the blend file",
    
                name="Export scene path",
    
                # Bug in POV-Ray RC3
                # description="Path to directory where the exported scene "
    
                            # "(POV and INI) is created",
    
                description="Path to directory where the files are created",
    
                maxlen=1024, subtype="DIR_PATH")
    
                name="Rendered image path",
    
                description="Full path to directory where the rendered image is "
                            "saved",
    
                maxlen=1024, subtype="DIR_PATH")
    
                name="LF in lists",
    
                description="Enable line breaks in lists (vectors and indices). "
                            "Disabled: lists are exported in one line",
    
                default=True)
    
        # Not a real pov option, just to know if we should write
    
                name="Enable Radiosity",
    
                description="Enable POV-Rays radiosity calculation",
    
                default=False)
    
                name="Advanced Options",
                description="Show advanced options",
                default=False)
    
                name="Enable Media",
                description="Enable POV-Rays atmospheric media",
                default=False)
    
                description="Number of samples taken from camera to first object "
    
                            "encountered along ray path for media calculation",
    
                min=1, max=100, default=35)
    
                name="Media Color", description="The atmospheric media color",
    
                precision=4, step=0.01, min=0, soft_max=1,
    
                default=(0.001, 0.001, 0.001),
    
                options={'ANIMATABLE'},
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                name="Enable Baking",
    
                description="Enable POV-Rays texture baking",
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                default=False)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                name="Indentation",
                description="Select the indentation type",
    
                items=(('NONE', "None", "No indentation"),
                       ('TAB', "Tabs", "Indentation with tabs"),
                       ('SPACE', "Spaces", "Indentation with spaces")),
                default='SPACE')
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                name="Quantity of spaces",
                description="The number of spaces for indentation",
    
                min=1, max=10, default=4)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                name="Enable Comments",
    
                description="Add comments to pov file",
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                default=True)
    
    
        # Real pov options
    
        command_line_switches = StringProperty(
                name="Command Line Switches",
    
                description="Command line switches consist of a + (plus) or - "
                            "(minus) sign, followed by one or more alphabetic "
                            "characters and possibly a numeric value",
    
                name="Anti-Alias", description="Enable Anti-Aliasing",
                default=True)
    
                name="Method",
    
                description="AA-sampling method. Type 1 is an adaptive, "
                            "non-recursive, super-sampling method. Type 2 is an "
                            "adaptive and recursive super-sampling method. Type 3 "
                            "is a stochastic halton based super-sampling method",
    
                items=(("0", "non-recursive AA", "Type 1 Sampling in POV-Ray"),
    
                       ("1", "recursive AA", "Type 2 Sampling in POV-Ray"),
                       ("2", "stochastic AA", "Type 3 Sampling in UberPOV")),
    
                default="1")
    
        antialias_confidence = FloatProperty(
    
                name="Antialias Confidence",
                description="how surely the computed color "
                            "of a given pixel is indeed"
                            "within the threshold error margin",
    
                min=0.0001, max=1.0000, default=0.9900, precision=4)
    
                name="Antialias Depth", description="Depth of pixel for sampling",
                min=1, max=9, default=3)
    
                name="Antialias Threshold", description="Tolerance for sub-pixels",
    
                min=0.0, max=1.0, soft_min=0.05, soft_max=0.5, default=0.03)
    
                description="Enable Jittering. Adds noise into the sampling "
                            "process (it should be avoided to use jitter in "
                            "animation)",
    
                name="Jitter Amount", description="Amount of jittering",
    
                min=0.0, max=1.0, soft_min=0.01, soft_max=1.0, default=1.0)
    
        antialias_gamma = FloatProperty(
                name="Antialias Gamma",
    
                description="POV-Ray compares gamma-adjusted values for super "
                            "sampling. Antialias Gamma sets the Gamma before "
                            "comparison",
    
                min=0.0, max=5.0, soft_min=0.01, soft_max=2.5, default=2.5)
    
        max_trace_level = IntProperty(
                name="Max Trace Level",
    
                description="Number of reflections/refractions allowed on ray "
                            "path",
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                min=1, max=256, default=5)
    
    
    #######NEW from Lanuhum
    
        adc_bailout_enable = BoolProperty(
                name="Enable",
                description="",
                default=False)
    
        adc_bailout = FloatProperty(
                name="ADC Bailout",
                description="",
                min=0.0, max=1000.0,default=0.00392156862745, precision=3)
    
        ambient_light_enable = BoolProperty(
                name="Enable",
                description="",
                default=False)
    
        ambient_light = FloatVectorProperty(
                name="Ambient Light", description="Ambient light is used to simulate the effect of inter-diffuse reflection",
                precision=4, step=0.01, min=0, soft_max=1,
                default=(1, 1, 1), options={'ANIMATABLE'}, subtype='COLOR')
    
        global_settings_advanced = BoolProperty(
                name="Advanced",
                description="",
                default=False)
    
        irid_wavelength_enable = BoolProperty(
                name="Enable",
                description="",
                default=False)
    
        irid_wavelength = FloatVectorProperty(
                name="Irid Wavelength", description="Iridescence calculations depend upon the dominant wavelengths of the primary colors of red, green and blue light.",
                precision=4, step=0.01, min=0, soft_max=1,
                default=(0.25,0.18,0.14), options={'ANIMATABLE'}, subtype='COLOR')
    
        charset = EnumProperty(
                name="Charset",
                description="This allows you to specify the assumed character set of all text strings.",
                items=(("ascii", "ASCII", ""),
                       ("utf8", "UTF-8", ""),
                       ("sys", "SYS", "")),
                default="utf8")
    
        max_intersections_enable = BoolProperty(
                name="Enable",
                description="",
                default=False)
    
        max_intersections = IntProperty(
                name="Max Intersections",
                description="POV-Ray uses a set of internal stacks to collect ray/object intersection points.",
                min=2, max=1024, default=64)
    
        number_of_waves_enable = BoolProperty(
                name="Enable",
                description="",
                default=False)
    
        number_of_waves = IntProperty(
                name="Number Waves",
                description="The waves and ripples patterns are generated by summing a series of waves, each with a slightly different center and size.",
                min=1, max=10, default=1000)
    
        noise_generator_enable = BoolProperty(
                name="Enable",
                description="",
                default=False)
    
        noise_generator = IntProperty(
                name="Noise Generator",
                description="There are three noise generators implemented.",
                min=1, max=3, default=2)
    
        ########################### PHOTONS #######################################
        photon_enable = BoolProperty(
                name="Photons",
                description="Enable global photons",
                default=False)
    
        photon_enable_count = BoolProperty(
                name="Spacing / Count",
                description="Enable count photons",
                default=False)
    
        photon_count = IntProperty(
                name="Count",
                description="Photons count",
                min=1, max=100000000, default=20000)
    
        photon_spacing = FloatProperty(
                name="Spacing",
    
                description="Average distance between photons on surfaces. half "
                            "this get four times as many surface photons",
                min=0.001, max=1.000, default=0.005,
                soft_min=0.001, soft_max=1.000, precision=3)
    
        photon_max_trace_level = IntProperty(
                name="Max Trace Level",
    
                description="Number of reflections/refractions allowed on ray "
                            "path",
    
                min=1, max=256, default=5)
    
    
        photon_adc_bailout = FloatProperty(
                name="ADC Bailout",
    
                description="The adc_bailout for photons. Use adc_bailout = "
    
                            "0.01 / brightest_ambient_object for good results",
    
                min=0.0, max=1000.0, default=0.1,
                soft_min=0.0, soft_max=1.0, precision=3)
    
                name="Gather Min", description="Minimum number of photons gathered"
                                               "for each point",
    
                min=1, max=256, default=20)
    
    
                name="Gather Max", description="Maximum number of photons gathered for each point",
                min=1, max=256, default=100)
    
        photon_map_file_save_load = EnumProperty(
                name="Operation",
                description="Load or Save photon map file",
                items=(("NONE", "None", ""),
                       ("save", "Save", ""),
                       ("load", "Load", "")),
                default="NONE")
    
        photon_map_filename = StringProperty(
                name="Filename",
                description="",
                maxlen=1024)
    
        photon_map_dir = StringProperty(
                name="Directory",
                description="",
                maxlen=1024, subtype="DIR_PATH")
    
        photon_map_file = StringProperty(
                name="File",
                description="",
                maxlen=1024, subtype="FILE_PATH")
    
        radio_adc_bailout = FloatProperty(
                name="ADC Bailout",
    
                description="The adc_bailout for radiosity rays. Use "
    
                            "adc_bailout = 0.01 / brightest_ambient_object for good results",
    
                min=0.0, max=1000.0, soft_min=0.0, soft_max=1.0, default=0.0039, precision=4)
    
        radio_always_sample = BoolProperty(
                name="Always Sample",
    
                description="Only use the data from the pretrace step and not gather "
    
                            "any new samples during the final radiosity pass",
    
        radio_brightness = FloatProperty(
                name="Brightness",
    
                description="Amount objects are brightened before being returned "
    
                min=0.0, max=1000.0, soft_min=0.0, soft_max=10.0, default=1.0)
    
    
                description="Number of rays for each new radiosity value to be calculated "
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                min=1, max=10000, soft_max=1600, default=35)
    
        radio_error_bound = FloatProperty(
                name="Error Bound",
    
                description="One of the two main speed/quality tuning values, "
    
                min=0.0, max=1000.0, soft_min=0.1, soft_max=10.0, default=1.8)
    
    
        radio_gray_threshold = FloatProperty(
                name="Gray Threshold",
    
                description="One of the two main speed/quality tuning values, "
    
                min=0.0, max=1.0, soft_min=0, soft_max=1, default=0.0)
    
    
        radio_low_error_factor = FloatProperty(
                name="Low Error Factor",
    
                description="Just enough samples is slightly blotchy. Low error changes error "
    
                            "tolerance for less critical last refining pass",
    
                min=0.000001, max=1.0, soft_min=0.000001, soft_max=1.0, default=0.5)
    
                name="Media", description="Radiosity estimation can be affected by media",
                default=False)
    
    
        radio_subsurface = BoolProperty(
                name="Subsurface", description="Radiosity estimation can be affected by Subsurface Light Transport",
                default=False)
    
    
        radio_minimum_reuse = FloatProperty(
                name="Minimum Reuse",
    
                description="Fraction of the screen width which sets the minimum radius of reuse "
    
                            "for each sample point (At values higher than 2% expect errors)",
    
                min=0.0, max=1.0, soft_min=0.1, soft_max=0.1, default=0.015, precision=3)
    
        radio_maximum_reuse = FloatProperty(
                name="Maximum Reuse",
                description="The maximum reuse parameter works in conjunction with, and is similar to that of minimum reuse, "
                            "the only difference being that it is an upper bound rather than a lower one.",
                min=0.0, max=1.0,default=0.2, precision=3)
    
    
        radio_nearest_count = IntProperty(
                name="Nearest Count",
    
                description="Number of old ambient values blended together to "
    
                min=1, max=20, default=5)
    
    
                name="Normals", description="Radiosity estimation can be affected by normals",
                default=False)
    
    
        radio_recursion_limit = IntProperty(
                name="Recursion Limit",
    
                description="how many recursion levels are used to calculate "
    
                min=1, max=20, default=1)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
        radio_pretrace_start = FloatProperty(
                name="Pretrace Start",
    
                description="Fraction of the screen width which sets the size of the "
    
                            "blocks in the mosaic preview first pass",
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                min=0.01, max=1.00, soft_min=0.02, soft_max=1.0, default=0.08)
    
    
        radio_pretrace_end = FloatProperty(
                name="Pretrace End",
    
                description="Fraction of the screen width which sets the size of the blocks "
    
                min=0.000925, max=1.00, soft_min=0.01, soft_max=1.00, default=0.04, precision=3)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
    
    ###############################################################################
    # Material POV properties.
    ###############################################################################
    
    class RenderPovSettingsMaterial(PropertyGroup):
    
                description="Newton's thin film interference (like an oil slick on a puddle of "
    
                            "water or the rainbow hues of a soap bubble.)",
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                name="Correct Reflection",
    
                description="Use same IOR as raytrace transparency to calculate mirror reflections. "
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                default=False)
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                name="Metallic Reflection",
                description="mirror reflections get colored as diffuse (for metallic materials)",
                default=False)
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                name="Conserve Energy",
    
                description="Light transmitted is more correctly reduced by mirror reflections, "
    
                            "also the sum of diffuse and translucency gets reduced below one ",
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                default=True)
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                name="amount",
    
                description="Contribution of the iridescence effect to the overall surface color. "
                            "As a rule of thumb keep to around 0.25 (25% contribution) or less, "
                            "but experiment. If the surface is coming out too white, try lowering "
    
                            "the diffuse and possibly the ambient values of the surface",
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                min=0.0, max=1.0, soft_min=0.01, soft_max=1.0, default=0.25)
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                name="thickness",
    
                description="A very thin film will have a high frequency of color changes while a "
    
                            "thick film will have large areas of color",
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                min=0.0, max=1000.0, soft_min=0.1, soft_max=10.0, default=1)
    
    
                name="turbulence", description="This parameter varies the thickness",
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                min=0.0, max=10.0, soft_min=0.000, soft_max=1.0, default=0)
    
    
        interior_fade_color = FloatVectorProperty(
    
                name="Interior Fade Color", description="Color of filtered attenuation for transparent "
    
                precision=4, step=0.01, min=0.0, soft_max=1.0,
                default=(0, 0, 0), options={'ANIMATABLE'}, subtype='COLOR')
    
        caustics_enable = BoolProperty(
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                name="Caustics",
    
                description="use only fake refractive caustics (default) or photon based "
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                default=True)
    
    
        fake_caustics = BoolProperty(
                name="Fake Caustics", description="use only (Fast) fake refractive caustics",
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                default=True)
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                name="Fake caustics power",
    
                description="Values typically range from 0.0 to 1.0 or higher. Zero is no caustics. "
                            "Low, non-zero values give broad hot-spots while higher values give "
    
                            "tighter, smaller simulated focal points",
    
                min=0.00, max=10.0, soft_min=0.00, soft_max=5.0, default=0.07)
    
        refraction_caustics = BoolProperty(
                name="Refractive Caustics", description="hotspots of light focused when going through the material",
                default=True)
    
                description="Light passing through will be separated according to wavelength. "
                            "This ratio of refractive indices for violet to red controls how much "
    
                            "the colors are spread out 1 = no dispersion, good values are 1.01 to 1.1",
    
                min=1.0000, max=10.000, soft_min=1.0000, soft_max=1.1000, precision=4, default=1.0000)
    
        photons_dispersion_samples = IntProperty(
                name="Dispersion Samples", description="Number of color-steps for dispersion",
                min=2, max=128, default=7)
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                name="Reflective Photon Caustics",
                description="Use this to make your Sauron's ring ;-P",
                default=False)
    
    
                       ("1", "Fake Caustics", "use fake caustics"),
    
                       ("2", "Photons Caustics", "use photons for refractive caustics")],
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                description="use fake caustics (fast) or true photons for refractive Caustics",
    
        ##################################CustomPOV Code############################
        replacement_text = StringProperty(
    
                description="Type the declared name in custom POV code or an external "
    
        def use_material_nodes_callback(self, context):
            if hasattr(context.space_data, "tree_type"):
                context.space_data.tree_type = 'ObjectNodeTree'
            mat=context.object.active_material
            if mat.pov.material_use_nodes:
                mat.use_nodes=True
                tree = mat.node_tree
                tree.name=mat.name
                links = tree.links
                default = True
                if len(tree.nodes) == 2:
                    o = 0
                    m = 0
                    for node in tree.nodes:
                        if node.type in {"OUTPUT","MATERIAL"}:
                            tree.nodes.remove(node)
                            default = True
                    for node in tree.nodes:
                        if node.bl_idname == 'PovrayOutputNode':
                            o+=1
                        if node.bl_idname == 'PovrayTextureNode':
                            m+=1
                    if o == 1 and m == 1:
                        default = False
                elif len(tree.nodes) == 0:
                    default = True
                else:
                    default = False
                if default:
                    output = tree.nodes.new('PovrayOutputNode')
                    output.location = 200,200
                    tmap = tree.nodes.new('PovrayTextureNode')
                    tmap.location = 0,200
                    links.new(tmap.outputs[0],output.inputs[0])
                    tmap.select = True
    
                    tree.nodes.active = tmap
    
            else:
                mat.use_nodes=False
    
    
        def use_texture_nodes_callback(self, context):
            tex=context.object.active_material.active_texture
            if tex.pov.texture_use_nodes:
                tex.use_nodes=True
                if len(tex.node_tree.nodes)==2:
                    for node in tex.node_tree.nodes:
                        if node.type in {"OUTPUT","CHECKER"}:
                            tex.node_tree.nodes.remove(node)
            else:
                tex.use_nodes=False
    
        def node_active_callback(self, context):
            items = []
            mat=context.material
            mat.node_tree.nodes
            for node in mat.node_tree.nodes:
                node.select=False
            for node in mat.node_tree.nodes:
                if node.name==mat.pov.material_active_node:
                    node.select=True
                    mat.node_tree.nodes.active=node
    
                    return node
    
        def node_enum_callback(self, context):
            items = []
            mat=context.material
            nodes=mat.node_tree.nodes
            for node in nodes:
                items.append(("%s"%node.name,"%s"%node.name,""))
            return items
    
        def pigment_normal_callback(self, context):
            render = context.scene.pov.render
            items = [("pigment", "Pigment", ""),("normal", "Normal", "")]
            if render == 'hgpovray':
                items = [("pigment", "Pigment", ""),("normal", "Normal", ""),("modulation", "Modulation", "")]
            return items
    
        def glow_callback(self, context):
            scene = context.scene
            ob = context.object
            ob.pov.mesh_write_as_old = ob.pov.mesh_write_as
            if scene.pov.render == 'uberpov' and ob.pov.glow:
                ob.pov.mesh_write_as = 'NONE'
            else:
                ob.pov.mesh_write_as = ob.pov.mesh_write_as_old
    
        material_use_nodes = BoolProperty(name="Use nodes", description="", update=use_material_nodes_callback, default=False)
        material_active_node = EnumProperty(name="Active node", description="", items=node_enum_callback, update=node_active_callback)
        preview_settings = BoolProperty(name="Preview Settings", description="",default=False)
        object_preview_transform = BoolProperty(name="Transform object", description="",default=False)
        object_preview_scale = FloatProperty(name="XYZ", min=0.5, max=2.0, default=1.0)
        object_preview_rotate = FloatVectorProperty(name="Rotate", description="", min=-180.0, max=180.0,default=(0.0,0.0,0.0), subtype='XYZ')
    
        object_preview_bgcontrast = FloatProperty(name="Contrast", min=0.0, max=1.0, default=0.5)
    
    
    ###############################################################################
    # Povray Nodes
    
    ###############################################################################
    class PovraySocketUniversal(bpy.types.NodeSocket):
        bl_idname = 'PovraySocketUniversal'
        bl_label = 'Povray Socket'
        value_unlimited = bpy.props.FloatProperty(default=0.0)
        value_0_1 = bpy.props.FloatProperty(min=0.0,max=1.0,default=0.0)
        value_0_10 = bpy.props.FloatProperty(min=0.0,max=10.0,default=0.0)
        value_000001_10 = bpy.props.FloatProperty(min=0.000001,max=10.0,default=0.0)
        value_1_9 = bpy.props.IntProperty(min=1,max=9,default=1)
        value_0_255 = bpy.props.IntProperty(min=0,max=255,default=0)
        percent = bpy.props.FloatProperty(min=0.0,max=100.0,default=0.0)
        def draw(self, context, layout, node, text):
            space = context.space_data
            tree = space.edit_tree
            links=tree.links
            if self.is_linked:
                value=[]
                for link in links:
                    if link.from_node==node:
                        inps=link.to_node.inputs
    
                        for inp in inps:
    
                            if inp.bl_idname=="PovraySocketFloat_0_1" and inp.is_linked:
                                prop="value_0_1"
                                if prop not in value:
                                    value.append(prop)
                            if inp.bl_idname=="PovraySocketFloat_000001_10" and inp.is_linked:
                                prop="value_000001_10"
                                if prop not in value:
                                    value.append(prop)
                            if inp.bl_idname=="PovraySocketFloat_0_10" and inp.is_linked:
                                prop="value_0_10"
                                if prop not in value:
                                    value.append(prop)
                            if inp.bl_idname=="PovraySocketInt_1_9" and inp.is_linked:
                                prop="value_1_9"
                                if prop not in value:
                                    value.append(prop)
                            if inp.bl_idname=="PovraySocketInt_0_255" and inp.is_linked:
                                prop="value_0_255"
                                if prop not in value:
                                    value.append(prop)
                            if inp.bl_idname=="PovraySocketFloatUnlimited" and inp.is_linked:
                                prop="value_unlimited"
                                if prop not in value:
                                    value.append(prop)
                if len(value)==1:
                    layout.prop(self, "%s"%value[0], text=text)
                else:
                    layout.prop(self, "percent", text="Percent")
            else:
                layout.prop(self, "percent", text=text)
        def draw_color(self, context, node):
            return (1, 0, 0, 1)
    
    class PovraySocketFloat_0_1(bpy.types.NodeSocket):
        bl_idname = 'PovraySocketFloat_0_1'
        bl_label = 'Povray Socket'
        default_value = bpy.props.FloatProperty(description="Input node Value_0_1",min=0,max=1,default=0)
        def draw(self, context, layout, node, text):
            if self.is_linked:
                layout.label(text)
            else:
                layout.prop(self, "default_value", text=text, slider=True)
    
        def draw_color(self, context, node):
            return (0.5, 0.7, 0.7, 1)
    
    class PovraySocketFloat_0_10(bpy.types.NodeSocket):
        bl_idname = 'PovraySocketFloat_0_10'
        bl_label = 'Povray Socket'
        default_value = bpy.props.FloatProperty(description="Input node Value_0_10",min=0,max=10,default=0)
        def draw(self, context, layout, node, text):
            if node.bl_idname == 'ShaderNormalMapNode' and node.inputs[2].is_linked:
                layout.label('')
                self.hide_value=True
            if self.is_linked:
                layout.label(text)
            else:
                layout.prop(self, "default_value", text=text, slider=True)
        def draw_color(self, context, node):
            return (0.65, 0.65, 0.65, 1)
    
    class PovraySocketFloat_10(bpy.types.NodeSocket):
        bl_idname = 'PovraySocketFloat_10'
        bl_label = 'Povray Socket'
        default_value = bpy.props.FloatProperty(description="Input node Value_10",min=-10,max=10,default=0)
        def draw(self, context, layout, node, text):
            if node.bl_idname == 'ShaderNormalMapNode' and node.inputs[2].is_linked:
                layout.label('')
                self.hide_value=True
            if self.is_linked:
                layout.label(text)
            else:
                layout.prop(self, "default_value", text=text, slider=True)
        def draw_color(self, context, node):
            return (0.65, 0.65, 0.65, 1)
    
    class PovraySocketFloatPositive(bpy.types.NodeSocket):
        bl_idname = 'PovraySocketFloatPositive'
        bl_label = 'Povray Socket'
        default_value = bpy.props.FloatProperty(description="Input Node Value Positive", min=0.0, default=0)
        def draw(self, context, layout, node, text):
            if self.is_linked:
                layout.label(text)
            else:
                layout.prop(self, "default_value", text=text, slider=True)
        def draw_color(self, context, node):
            return (0.045, 0.005, 0.136, 1)
    
    class PovraySocketFloat_000001_10(bpy.types.NodeSocket):
        bl_idname = 'PovraySocketFloat_000001_10'
        bl_label = 'Povray Socket'
        default_value = bpy.props.FloatProperty(min=0.000001,max=10,default=0.000001)
        def draw(self, context, layout, node, text):
            if self.is_output or self.is_linked:
                layout.label(text)
            else:
                layout.prop(self, "default_value", text=text, slider=True)
        def draw_color(self, context, node):
            return (1, 0, 0, 1)
    
    class PovraySocketFloatUnlimited(bpy.types.NodeSocket):
        bl_idname = 'PovraySocketFloatUnlimited'
        bl_label = 'Povray Socket'
        default_value = bpy.props.FloatProperty(default = 0.0)
        def draw(self, context, layout, node, text):
            if self.is_linked:
                layout.label(text)
            else:
                layout.prop(self, "default_value", text=text, slider=True)
        def draw_color(self, context, node):
            return (0.7, 0.7, 1, 1)
    
    class PovraySocketInt_1_9(bpy.types.NodeSocket):
        bl_idname = 'PovraySocketInt_1_9'
        bl_label = 'Povray Socket'
        default_value = bpy.props.IntProperty(description="Input node Value_1_9",min=1,max=9,default=6)
        def draw(self, context, layout, node, text):
            if self.is_linked:
                layout.label(text)
            else:
                layout.prop(self, "default_value", text=text)
        def draw_color(self, context, node):
            return (1, 0.7, 0.7, 1)
    
    class PovraySocketInt_0_256(bpy.types.NodeSocket):
        bl_idname = 'PovraySocketInt_0_256'
        bl_label = 'Povray Socket'
        default_value = bpy.props.IntProperty(min=0,max=255,default=0)
        def draw(self, context, layout, node, text):
            if self.is_linked:
                layout.label(text)
            else:
                layout.prop(self, "default_value", text=text)
        def draw_color(self, context, node):
            return (0.5, 0.5, 0.5, 1)
    
    
    class PovraySocketPattern(bpy.types.NodeSocket):
        bl_idname = 'PovraySocketPattern'
        bl_label = 'Povray Socket'
    
        default_value = bpy.props.EnumProperty(
                name="Pattern",
                description="Select the pattern",
                items=(('boxed', "Boxed", ""),('brick', "Brick", ""),('cells', "Cells", ""), ('checker', "Checker", ""),
                       ('granite', "Granite", ""),('leopard', "Leopard", ""),('marble', "Marble", ""),
                       ('onion', "Onion", ""),('planar', "Planar", ""), ('quilted', "Quilted", ""),
                       ('ripples', "Ripples", ""),  ('radial', "Radial", ""),('spherical', "Spherical", ""),
                       ('spotted', "Spotted", ""), ('waves', "Waves", ""), ('wood', "Wood", ""),
                       ('wrinkles', "Wrinkles", "")),
                default='granite')
    
        def draw(self, context, layout, node, text):
            if self.is_output or self.is_linked:
                layout.label("Pattern")
            else:
                layout.prop(self, "default_value", text=text)
    
        def draw_color(self, context, node):
            return (1, 1, 1, 1)
    
    class PovraySocketColor(bpy.types.NodeSocket):
        bl_idname = 'PovraySocketColor'
        bl_label = 'Povray Socket'
    
        default_value = bpy.props.FloatVectorProperty(
                precision=4, step=0.01, min=0, soft_max=1,
                default=(0.0, 0.0, 0.0), options={'ANIMATABLE'}, subtype='COLOR')
    
        def draw(self, context, layout, node, text):
            if self.is_output or self.is_linked:
                layout.label(text)
            else:
                layout.prop(self, "default_value", text=text)
    
        def draw_color(self, context, node):
            return (1, 1, 0, 1)
    
    class PovraySocketColorRGBFT(bpy.types.NodeSocket):
        bl_idname = 'PovraySocketColorRGBFT'
        bl_label = 'Povray Socket'
    
        default_value = bpy.props.FloatVectorProperty(
                precision=4, step=0.01, min=0, soft_max=1,
                default=(0.0, 0.0, 0.0), options={'ANIMATABLE'}, subtype='COLOR')
        f = bpy.props.FloatProperty(default = 0.0,min=0.0,max=1.0)
        t = bpy.props.FloatProperty(default = 0.0,min=0.0,max=1.0)
        def draw(self, context, layout, node, text):
            if self.is_output or self.is_linked:
                layout.label(text)
            else:
                layout.prop(self, "default_value", text=text)
    
        def draw_color(self, context, node):
            return (1, 1, 0, 1)
    
    class PovraySocketTexture(bpy.types.NodeSocket):
        bl_idname = 'PovraySocketTexture'
        bl_label = 'Povray Socket'
        default_value = bpy.props.IntProperty()
        def draw(self, context, layout, node, text):
            layout.label(text)
    
        def draw_color(self, context, node):
            return (0, 1, 0, 1)
    
    
    
    class PovraySocketTransform(bpy.types.NodeSocket):
        bl_idname = 'PovraySocketTransform'
        bl_label = 'Povray Socket'
        default_value = bpy.props.IntProperty(min=0,max=255,default=0)
        def draw(self, context, layout, node, text):
            layout.label(text)
    
        def draw_color(self, context, node):
            return (99/255, 99/255, 199/255, 1)
    
    class PovraySocketNormal(bpy.types.NodeSocket):
        bl_idname = 'PovraySocketNormal'
        bl_label = 'Povray Socket'
        default_value = bpy.props.IntProperty(min=0,max=255,default=0)
        def draw(self, context, layout, node, text):
            layout.label(text)
    
        def draw_color(self, context, node):
            return (0.65, 0.65, 0.65, 1)
    
    class PovraySocketSlope(bpy.types.NodeSocket):
        bl_idname = 'PovraySocketSlope'
        bl_label = 'Povray Socket'
        default_value = bpy.props.FloatProperty(min = 0.0, max = 1.0)
        height = bpy.props.FloatProperty(min = 0.0, max = 10.0)
        slope = bpy.props.FloatProperty(min = -10.0, max = 10.0)
        def draw(self, context, layout, node, text):
            if self.is_output or self.is_linked:
                layout.label(text)
            else:
                layout.prop(self,'default_value',text='')
                layout.prop(self,'height',text='')
                layout.prop(self,'slope',text='')
        def draw_color(self, context, node):
            return (0, 0, 0, 1)
    
    class PovraySocketMap(bpy.types.NodeSocket):
        bl_idname = 'PovraySocketMap'
        bl_label = 'Povray Socket'
        default_value = bpy.props.StringProperty()
        def draw(self, context, layout, node, text):
            layout.label(text)
        def draw_color(self, context, node):
            return (0.2, 0, 0.2, 1)
    
    class PovrayShaderNodeCategory(NodeCategory):
        @classmethod
        def poll(cls, context):
            return context.space_data.tree_type == 'ObjectNodeTree'
    
    class PovrayTextureNodeCategory(NodeCategory):
        @classmethod
        def poll(cls, context):
            return context.space_data.tree_type == 'TextureNodeTree'
    
    class PovraySceneNodeCategory(NodeCategory):
        @classmethod
        def poll(cls, context):
            return context.space_data.tree_type == 'CompositorNodeTree'
    
    node_categories = [
    
        PovrayShaderNodeCategory("SHADEROUTPUT", "Output", items=[
            NodeItem("PovrayOutputNode"),
            ]),
    
        PovrayShaderNodeCategory("SIMPLE", "Simple texture", items=[
            NodeItem("PovrayTextureNode"),
            ]),
    
        PovrayShaderNodeCategory("MAPS", "Maps", items=[
            NodeItem("PovrayBumpMapNode"),
            NodeItem("PovrayColorImageNode"),
            NodeItem("ShaderNormalMapNode"),
            NodeItem("PovraySlopeNode"),
            NodeItem("ShaderTextureMapNode"),
            NodeItem("ShaderNodeValToRGB"),
            ]),
    
        PovrayShaderNodeCategory("OTHER", "Other patterns", items=[
            NodeItem("PovrayImagePatternNode"),
            NodeItem("ShaderPatternNode"),
            ]),
    
        PovrayShaderNodeCategory("COLOR", "Color", items=[
            NodeItem("PovrayPigmentNode"),
            ]),
    
        PovrayShaderNodeCategory("TRANSFORM", "Transform", items=[
            NodeItem("PovrayMappingNode"),
            NodeItem("PovrayMultiplyNode"),
            NodeItem("PovrayModifierNode"),
            NodeItem("PovrayTransformNode"),
            NodeItem("PovrayValueNode"),
            ]),
    
        PovrayShaderNodeCategory("FINISH", "Finish", items=[
            NodeItem("PovrayFinishNode"),
            NodeItem("PovrayDiffuseNode"),
            NodeItem("PovraySpecularNode"),
            NodeItem("PovrayPhongNode"),
            NodeItem("PovrayAmbientNode"),
            NodeItem("PovrayMirrorNode"),
            NodeItem("PovrayIridescenceNode"),
            NodeItem("PovraySubsurfaceNode"),
    
    
        PovrayShaderNodeCategory("CYCLES", "Cycles", items=[