Skip to content
Snippets Groups Projects
nodes.py 44.3 KiB
Newer Older
  • Learn to ignore specific revisions
  • # ##### 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>
    
    import bpy
    
    
    from bpy.utils import register_class
    
    from bpy.types import Node, ShaderNodeTree, CompositorNodeTree, TextureNodeTree#, NodeSocket
    from bpy.props import (
            StringProperty,
            BoolProperty,
            IntProperty,
            FloatProperty,
            FloatVectorProperty,
            EnumProperty,
            #PointerProperty,
            #CollectionProperty,
            )
    
    
    
    
    ############### object
    
    
    class ObjectNodeTree(bpy.types.NodeTree):
        '''Povray Material Nodes'''
    
        bl_idname = 'ObjectNodeTree'
        bl_label = 'Povray Object Nodes'
        bl_icon = 'PLUGIN'
    
        @classmethod
        def poll(cls, context):
            return context.scene.render.engine == 'POVRAY_RENDER'
    
        @classmethod
        def get_from_context(cls, context):
            ob = context.active_object
    
            if ob and ob.type not in {'LIGHT'}:
    
                ma = ob.active_material
    
                if ma is not None:
    
                    nt_name = ma.node_tree
                    if nt_name != '':
                        return nt_name, ma, ma
            return (None, None, None)
    
        def update(self):
            self.refresh = True
    ################### output #############################################################################################
    
    class PovrayOutputNode(Node, ObjectNodeTree):
        '''Output'''
        bl_idname = 'PovrayOutputNode'
        bl_label = 'Output'
        bl_icon = 'SOUND'
    
        def init(self, context):
    
            self.inputs.new('PovraySocketTexture', "Texture")
    
        def draw_buttons(self, context, layout):
    
            ob=context.object
            layout.prop(ob.pov, "object_ior",slider=True)
    
        def draw_buttons_ext(self, context, layout):
    
            ob=context.object
            layout.prop(ob.pov, "object_ior",slider=True)
    
        def draw_label(self):
            return "Output"
    
    
    
    ################### material ###########################################################################################
    class PovrayTextureNode(Node, ObjectNodeTree):
        '''Texture'''
        bl_idname = 'PovrayTextureNode'
        bl_label = 'Simple texture'
        bl_icon = 'SOUND'
    
        def init(self, context):
    
            color=self.inputs.new('PovraySocketColor', "Pigment")
            color.default_value=(1,1,1)
            normal=self.inputs.new('NodeSocketFloat', "Normal")
            normal.hide_value=True
            finish=self.inputs.new('NodeSocketVector', "Finish")
            finish.hide_value=True
    
            self.outputs.new('PovraySocketTexture', "Texture")
    
        def draw_label(self):
            return "Simple texture"
    
    class PovrayFinishNode(Node, ObjectNodeTree):
        '''Finish'''
        bl_idname = 'PovrayFinishNode'
        bl_label = 'Finish'
        bl_icon = 'SOUND'
    
        def init(self, context):
    
            self.inputs.new('PovraySocketFloat_0_1', "Emission")
            ambient=self.inputs.new('NodeSocketVector', "Ambient")
            ambient.hide_value=True
            diffuse=self.inputs.new('NodeSocketVector', "Diffuse")
            diffuse.hide_value=True
            specular=self.inputs.new('NodeSocketVector', "Highlight")
            specular.hide_value=True
            mirror=self.inputs.new('NodeSocketVector', "Mirror")
            mirror.hide_value=True
            iridescence=self.inputs.new('NodeSocketVector', "Iridescence")
            iridescence.hide_value=True
            subsurface=self.inputs.new('NodeSocketVector', "Translucency")
            subsurface.hide_value=True
            self.outputs.new('NodeSocketVector', "Finish")
    
        def draw_label(self):
            return "Finish"
    
    class PovrayDiffuseNode(Node, ObjectNodeTree):
        '''Diffuse'''
        bl_idname = 'PovrayDiffuseNode'
        bl_label = 'Diffuse'
        bl_icon = 'SOUND'
    
        def init(self, context):
    
            intensity=self.inputs.new('PovraySocketFloat_0_1', "Intensity")
            intensity.default_value=0.8
            albedo=self.inputs.new('NodeSocketBool', "Albedo")
            albedo.default_value=False
            brilliance=self.inputs.new('PovraySocketFloat_0_10', "Brilliance")
            brilliance.default_value=1.8
            self.inputs.new('PovraySocketFloat_0_1', "Crand")
            self.outputs.new('NodeSocketVector', "Diffuse")
    
        def draw_label(self):
            return "Diffuse"
    
    class PovrayPhongNode(Node, ObjectNodeTree):
        '''Phong'''
        bl_idname = 'PovrayPhongNode'
        bl_label = 'Phong'
        bl_icon = 'SOUND'
    
        def init(self, context):
    
            albedo=self.inputs.new('NodeSocketBool', "Albedo")
            intensity=self.inputs.new('PovraySocketFloat_0_1', "Intensity")
            intensity.default_value=0.8
            phong_size=self.inputs.new('PovraySocketInt_0_256', "Size")
            phong_size.default_value=60
            metallic=self.inputs.new('PovraySocketFloat_0_1', "Metallic")
    
            self.outputs.new('NodeSocketVector', "Phong")
    
        def draw_label(self):
            return "Phong"
    
    class PovraySpecularNode(Node, ObjectNodeTree):
        '''Specular'''
        bl_idname = 'PovraySpecularNode'
        bl_label = 'Specular'
        bl_icon = 'SOUND'
    
        def init(self, context):
    
            albedo=self.inputs.new('NodeSocketBool', "Albedo")
            intensity=self.inputs.new('PovraySocketFloat_0_1', "Intensity")
            intensity.default_value=0.8
            roughness=self.inputs.new('PovraySocketFloat_0_1', "Roughness")
            roughness.default_value=0.02
            metallic=self.inputs.new('PovraySocketFloat_0_1', "Metallic")
    
            self.outputs.new('NodeSocketVector', "Specular")
    
        def draw_label(self):
            return "Specular"
    
    class PovrayMirrorNode(Node, ObjectNodeTree):
        '''Mirror'''
        bl_idname = 'PovrayMirrorNode'
        bl_label = 'Mirror'
        bl_icon = 'SOUND'
    
        def init(self, context):
    
            color=self.inputs.new('PovraySocketColor', "Color")
            color.default_value=(1,1,1)
            metallic=self.inputs.new('PovraySocketFloat_0_1', "Metallic")
            metallic.default_value=1.0
            exponent=self.inputs.new('PovraySocketFloat_0_1', "Exponent")
            exponent.default_value=1.0
            self.inputs.new('PovraySocketFloat_0_1', "Falloff")
            self.inputs.new('NodeSocketBool', "Fresnel")
            self.inputs.new('NodeSocketBool', "Conserve energy")
            self.outputs.new('NodeSocketVector', "Mirror")
    
        def draw_label(self):
            return "Mirror"
    
    class PovrayAmbientNode(Node, ObjectNodeTree):
        '''Ambient'''
        bl_idname = 'PovrayAmbientNode'
        bl_label = 'Ambient'
        bl_icon = 'SOUND'
    
        def init(self, context):
    
            self.inputs.new('PovraySocketColor', "Ambient")
    
            self.outputs.new('NodeSocketVector', "Ambient")
    
        def draw_label(self):
            return "Ambient"
    
    class PovrayIridescenceNode(Node, ObjectNodeTree):
        '''Iridescence'''
        bl_idname = 'PovrayIridescenceNode'
        bl_label = 'Iridescence'
        bl_icon = 'SOUND'
    
        def init(self, context):
    
            amount=self.inputs.new('NodeSocketFloat', "Amount")
            amount.default_value=0.25
            thickness=self.inputs.new('NodeSocketFloat', "Thickness")
            thickness.default_value=1
            self.inputs.new('NodeSocketFloat', "Turbulence")
    
            self.outputs.new('NodeSocketVector', "Iridescence")
    
        def draw_label(self):
            return "Iridescence"
    
    class PovraySubsurfaceNode(Node, ObjectNodeTree):
        '''Subsurface'''
        bl_idname = 'PovraySubsurfaceNode'
        bl_label = 'Subsurface'
        bl_icon = 'SOUND'
    
        def init(self, context):
    
            translucency=self.inputs.new('NodeSocketColor', "Translucency")
            translucency.default_value=(0,0,0,1)
            energy=self.inputs.new('PovraySocketInt_0_256', "Energy")
            energy.default_value=20
            self.outputs.new('NodeSocketVector', "Translucency")
    
        def draw_buttons(self, context, layout):
            scene=context.scene
            layout.prop(scene.pov, "sslt_enable",text="SSLT")
    
    
        def draw_buttons_ext(self, context, layout):
            scene=context.scene
            layout.prop(scene.pov, "sslt_enable",text="SSLT")
    
        def draw_label(self):
            return "Subsurface"
    
    #####################################################################################################
    
    class PovrayMappingNode(Node, ObjectNodeTree):
        '''Mapping'''
        bl_idname = 'PovrayMappingNode'
        bl_label = 'Mapping'
        bl_icon = 'SOUND'
    
    
        warp_type: EnumProperty(
    
                name="Warp Types",
                description="Select the type of warp",
                items=( ('cubic', "Cubic", ""),  ('cylindrical', "Cylindrical", ""),('planar', "Planar", ""),
                        ('spherical', "Spherical", ""),('toroidal', "Toroidal", ""),
                        ('uv_mapping', "UV", ""),
                        ('NONE', "None", "No indentation")),
                default='NONE')
    
    
        warp_orientation: EnumProperty(
    
                name="Warp Orientation",
                description="Select the orientation of warp",
                items=(('x', "X", ""), ('y', "Y", ""), ('z', "Z", "")),
                default='y')
    
    
        warp_dist_exp: FloatProperty(
    
                name="Distance exponent",
                description="Distance exponent",
                min=0.0, max=100.0, default=1.0)
    
        warp_tor_major_radius: FloatProperty(
    
                name="Major radius",
                description="Torus is distance from major radius",
                min=0.0, max=5.0, default=1.0)
    
        def init(self, context):
            self.outputs.new('NodeSocketVector', "Mapping")
    
        def draw_buttons(self, context, layout):
    
            column=layout.column()
            column.prop(self,"warp_type",text="Warp type")
            if self.warp_type in {'toroidal','spherical','cylindrical','planar'}:
                column.prop(self,"warp_orientation",text="Orientation")
                column.prop(self,"warp_dist_exp",text="Exponent")
            if self.warp_type=='toroidal':
                column.prop(self,"warp_tor_major_radius",text="Major R")
    
        def draw_buttons_ext(self, context, layout):
    
            column=layout.column()
            column.prop(self,"warp_type",text="Warp type")
            if self.warp_type in {'toroidal','spherical','cylindrical','planar'}:
                column.prop(self,"warp_orientation",text="Orientation")
                column.prop(self,"warp_dist_exp",text="Exponent")
            if self.warp_type=='toroidal':
                column.prop(self,"warp_tor_major_radius",text="Major R")
    
        def draw_label(self):
            return "Mapping"
    
    class PovrayMultiplyNode(Node, ObjectNodeTree):
        '''Multiply'''
        bl_idname = 'PovrayMultiplyNode'
        bl_label = 'Multiply'
        bl_icon = 'SOUND'
    
    
                name="X",
                description="Number of repeats",
                min=1.0, max=10000.0, default=1.0)
    
    
                name="Y",
                description="Number of repeats",
                min=1.0, max=10000.0, default=1.0)
    
    
                name="Z",
                description="Number of repeats",
                min=1.0, max=10000.0, default=1.0)
    
    
        def init(self, context):
            self.outputs.new('NodeSocketVector', "Amount")
    
        def draw_buttons(self, context, layout):
    
            column=layout.column()
    
            column.label(text="Amount")
    
            row=column.row(align=True)
            row.prop(self,"amount_x")
            row.prop(self,"amount_y")
            row.prop(self,"amount_z")
    
        def draw_buttons_ext(self, context, layout):
    
            column=layout.column()
    
            column.label(text="Amount")
    
            row=column.row(align=True)
            row.prop(self,"amount_x")
            row.prop(self,"amount_y")
            row.prop(self,"amount_z")
    
        def draw_label(self):
            return "Multiply"
    
    class PovrayTransformNode(Node, ObjectNodeTree):
        '''Transform'''
        bl_idname = 'PovrayTransformNode'
        bl_label = 'Transform'
        bl_icon = 'SOUND'
    
        def init(self, context):
    
            self.inputs.new('PovraySocketFloatUnlimited', "Translate x")
            self.inputs.new('PovraySocketFloatUnlimited', "Translate y")
            self.inputs.new('PovraySocketFloatUnlimited', "Translate z")
            self.inputs.new('PovraySocketFloatUnlimited', "Rotate x")
            self.inputs.new('PovraySocketFloatUnlimited', "Rotate y")
            self.inputs.new('PovraySocketFloatUnlimited', "Rotate z")
            sX = self.inputs.new('PovraySocketFloatUnlimited', "Scale x")
            sX.default_value = 1.0
            sY = self.inputs.new('PovraySocketFloatUnlimited', "Scale y")
            sY.default_value = 1.0
            sZ = self.inputs.new('PovraySocketFloatUnlimited', "Scale z")
            sZ.default_value = 1.0
    
            self.outputs.new('NodeSocketVector', "Transform")
    
        def draw_label(self):
            return "Transform"
    
    class PovrayValueNode(Node, ObjectNodeTree):
        '''Value'''
        bl_idname = 'PovrayValueNode'
        bl_label = 'Value'
        bl_icon = 'SOUND'
    
        def init(self, context):
    
            self.outputs.new('PovraySocketUniversal', "Value")
    
        def draw_label(self):
            return "Value"
    
    class PovrayModifierNode(Node, ObjectNodeTree):
        '''Modifier'''
        bl_idname = 'PovrayModifierNode'
        bl_label = 'Modifier'
        bl_icon = 'SOUND'
    
        def init(self, context):
    
            turb_x=self.inputs.new('PovraySocketFloat_0_10', "Turb X")
            turb_x.default_value=0.1
            turb_y=self.inputs.new('PovraySocketFloat_0_10', "Turb Y")
            turb_y.default_value=0.1
            turb_z=self.inputs.new('PovraySocketFloat_0_10', "Turb Z")
            turb_z.default_value=0.1
            octaves=self.inputs.new('PovraySocketInt_1_9', "Octaves")
            octaves.default_value=1
            lambat=self.inputs.new('PovraySocketFloat_0_10', "Lambda")
            lambat.default_value=2.0
            omega=self.inputs.new('PovraySocketFloat_0_10', "Omega")
            omega.default_value=0.5
            freq=self.inputs.new('PovraySocketFloat_0_10', "Frequency")
            freq.default_value=2.0
            self.inputs.new('PovraySocketFloat_0_10', "Phase")
    
            self.outputs.new('NodeSocketVector', "Modifier")
    
        def draw_label(self):
            return "Modifier"
    
    class PovrayPigmentNode(Node, ObjectNodeTree):
        '''Pigment'''
        bl_idname = 'PovrayPigmentNode'
        bl_label = 'Color'
    
        def init(self, context):
    
            color = self.inputs.new('PovraySocketColor', "Color")
            color.default_value = (1,1,1)
            povfilter = self.inputs.new('PovraySocketFloat_0_1', "Filter")
            transmit = self.inputs.new('PovraySocketFloat_0_1', "Transmit")
            self.outputs.new('NodeSocketColor', "Pigment")
    
        def draw_label(self):
            return "Color"
    
    class PovrayColorImageNode(Node, ObjectNodeTree):
        '''ColorImage'''
        bl_idname = 'PovrayColorImageNode'
        bl_label = 'Image map'
    
    
        map_type: bpy.props.EnumProperty(
    
                name="Map type",
                description="",
                items=( ('uv_mapping', "UV", ""),
    
                        ('0', "Planar", "Default planar mapping"),
                        ('1', "Spherical", "Spherical mapping"),
                        ('2', "Cylindrical", "Cylindrical mapping"),
                        ('5', "Torroidal", "Torus or donut shaped mapping")),
    
        image: StringProperty(maxlen=1024) # , subtype="FILE_PATH"
        interpolate: EnumProperty(
    
                name="Interpolate",
    
                description="Adding the interpolate keyword can smooth the jagged look of a bitmap",
                items=(
                    ('2', "Bilinear", "Gives bilinear interpolation"),
                    ('4', "Normalized", "Gives normalized distance"),
                ),
    
        premultiplied: BoolProperty(default=False)
        once: BoolProperty(description="Not to repeat", default=False)
    
    
        def init(self, context):
    
            gamma=self.inputs.new('PovraySocketFloat_000001_10', "Gamma")
            gamma.default_value=2.0
            transmit=self.inputs.new('PovraySocketFloat_0_1', "Transmit")
            povfilter=self.inputs.new('PovraySocketFloat_0_1', "Filter")
            mapping=self.inputs.new('NodeSocketVector', "Mapping")
            mapping.hide_value=True
            transform=self.inputs.new('NodeSocketVector', "Transform")
            transform.hide_value=True
            modifier=self.inputs.new('NodeSocketVector', "Modifier")
            modifier.hide_value=True
    
            self.outputs.new('NodeSocketColor', "Pigment")
    
        def draw_buttons(self, context, layout):
    
            column=layout.column()
            im=None
            for image in bpy.data.images:
                if image.name == self.image:
                    im=image
    
    NBurn's avatar
    NBurn committed
            split = column.split(factor=0.8,align=True)
    
            split.prop_search(self,"image",context.blend_data,"images",text="")
    
            split.operator("pov.imageopen",text="",icon="FILEBROWSER")
    
            if im is not None:
    
                column.prop(im,"source",text="")
            column.prop(self,"map_type",text="")
            column.prop(self,"interpolate",text="")
            row=column.row()
            row.prop(self,"premultiplied",text="Premul")
            row.prop(self,"once",text="Once")
    
        def draw_buttons_ext(self, context, layout):
    
            column=layout.column()
            im=None
            for image in bpy.data.images:
                if image.name == self.image:
                    im=image
    
    NBurn's avatar
    NBurn committed
            split = column.split(factor=0.8,align=True)
    
            split.prop_search(self,"image",context.blend_data,"images",text="")
    
            split.operator("pov.imageopen",text="",icon="FILEBROWSER")
    
            if im is not None:
    
                column.prop(im,"source",text="")
            column.prop(self,"map_type",text="")
            column.prop(self,"interpolate",text="")
            row=column.row()
            row.prop(self,"premultiplied",text="Premul")
            row.prop(self,"once",text="Once")
    
        def draw_label(self):
            return "Image map"
    
    class PovrayBumpMapNode(Node, ObjectNodeTree):
        '''BumpMap'''
        bl_idname = 'PovrayBumpMapNode'
        bl_label = 'Bump map'
        bl_icon = 'SOUND'
    
    
        map_type : bpy.props.EnumProperty(
    
                name="Map type",
                description="",
    
                items=(
                    ('uv_mapping', "UV", ""),
                    ('0', "Planar", "Default planar mapping"),
                    ('1', "Spherical", "Spherical mapping"),
                    ('2', "Cylindrical", "Cylindrical mapping"),
                    ('5', "Torroidal", "Torus or donut shaped mapping")
                ),
    
        image : StringProperty(maxlen=1024) # , subtype="FILE_PATH"
        interpolate : EnumProperty(
    
                name="Interpolate",
    
                description="Adding the interpolate keyword can smooth the jagged look of a bitmap",
                items=(
                    ('2', "Bilinear", "Gives bilinear interpolation"),
                    ('4', "Normalized", "Gives normalized distance"),
                ),
    
        once : BoolProperty(description="Not to repeat", default=False)
    
    
        def init(self, context):
    
            self.inputs.new('PovraySocketFloat_0_10', "Normal")
            mapping=self.inputs.new('NodeSocketVector', "Mapping")
            mapping.hide_value=True
            transform=self.inputs.new('NodeSocketVector', "Transform")
            transform.hide_value=True
            modifier=self.inputs.new('NodeSocketVector', "Modifier")
            modifier.hide_value=True
    
            normal=self.outputs.new('NodeSocketFloat', "Normal")
            normal.hide_value=True
    
        def draw_buttons(self, context, layout):
    
            column=layout.column()
            im=None
            for image in bpy.data.images:
                if image.name == self.image:
                    im=image
            split = column.split(percentage=0.8,align=True)
            split.prop_search(self,"image",context.blend_data,"images",text="")
    
            split.operator("pov.imageopen",text="",icon="FILEBROWSER")
    
            if im is not None:
    
                column.prop(im,"source",text="")
            column.prop(self,"map_type",text="")
            column.prop(self,"interpolate",text="")
            column.prop(self,"once",text="Once")
    
        def draw_buttons_ext(self, context, layout):
    
            column=layout.column()
            im=None
            for image in bpy.data.images:
                if image.name == self.image:
                    im=image
            split = column.split(percentage=0.8,align=True)
            split.prop_search(self,"image",context.blend_data,"images",text="")
    
            split.operator("pov.imageopen",text="",icon="FILEBROWSER")
    
            if im is not None:
    
                column.prop(im,"source",text="")
            column.prop(self,"map_type",text="")
            column.prop(self,"interpolate",text="")
            column.prop(self,"once",text="Once")
    
        def draw_label(self):
            return "Bump Map"
    
    class PovrayImagePatternNode(Node, ObjectNodeTree):
        '''ImagePattern'''
        bl_idname = 'PovrayImagePatternNode'
        bl_label = 'Image pattern'
        bl_icon = 'SOUND'
    
    
        map_type: bpy.props.EnumProperty(
    
                name="Map type",
                description="",
    
                items=(
                    ('uv_mapping', "UV", ""),
                    ('0', "Planar", "Default planar mapping"),
                    ('1', "Spherical", "Spherical mapping"),
                    ('2', "Cylindrical", "Cylindrical mapping"),
                    ('5', "Torroidal", "Torus or donut shaped mapping"),
                ),
    
        image: StringProperty(maxlen=1024) # , subtype="FILE_PATH"
        interpolate: EnumProperty(
    
                name="Interpolate",
    
                description="Adding the interpolate keyword can smooth the jagged look of a bitmap",
                items=(
                    ('2', "Bilinear", "Gives bilinear interpolation"),
                    ('4', "Normalized", "Gives normalized distance"),
                ),
    
        premultiplied: BoolProperty(default=False)
        once: BoolProperty(description="Not to repeat", default=False)
        use_alpha: BoolProperty(default=True)
    
        def init(self, context):
    
            gamma=self.inputs.new('PovraySocketFloat_000001_10', "Gamma")
            gamma.default_value=2.0
    
            self.outputs.new('PovraySocketPattern', "Pattern")
    
        def draw_buttons(self, context, layout):
    
            column=layout.column()
            im=None
            for image in bpy.data.images:
                if image.name == self.image:
                    im=image
    
    NBurn's avatar
    NBurn committed
            split = column.split(factor=0.8,align=True)
    
            split.prop_search(self,"image",context.blend_data,"images",text="")
    
            split.operator("pov.imageopen",text="",icon="FILEBROWSER")
    
            if im is not None:
    
                column.prop(im,"source",text="")
            column.prop(self,"map_type",text="")
            column.prop(self,"interpolate",text="")
            row=column.row()
            row.prop(self,"premultiplied",text="Premul")
            row.prop(self,"once",text="Once")
            column.prop(self,"use_alpha",text="Use alpha")
    
        def draw_buttons_ext(self, context, layout):
    
            column=layout.column()
            im=None
            for image in bpy.data.images:
                if image.name == self.image:
                    im=image
    
    NBurn's avatar
    NBurn committed
            split = column.split(factor=0.8,align=True)
    
            split.prop_search(self,"image",context.blend_data,"images",text="")
    
            split.operator("pov.imageopen",text="",icon="FILEBROWSER")
    
            if im is not None:
    
                column.prop(im,"source",text="")
            column.prop(self,"map_type",text="")
            column.prop(self,"interpolate",text="")
            row=column.row()
            row.prop(self,"premultiplied",text="Premul")
            row.prop(self,"once",text="Once")
    
        def draw_label(self):
            return "Image pattern"
    
    class ShaderPatternNode(Node, ObjectNodeTree):
        '''Pattern'''
        bl_idname = 'ShaderPatternNode'
        bl_label = 'Other patterns'
    
    
                name="Pattern",
                description="Agate, Crackle, Gradient, Pavement, Spiral, Tiling",
                items=(('agate', "Agate", ""),('crackle', "Crackle", ""),('gradient', "Gradient", ""),
                       ('pavement', "Pavement", ""),
                       ('spiral1', "Spiral 1", ""),
                       ('spiral2', "Spiral 2", ""),
                       ('tiling', "Tiling", "")),
                default='agate')
    
    
                name="Agate turb",
                description="Agate turbulence",
                min=0.0, max=100.0, default=0.5)
    
    
        crackle_form_x : FloatProperty(
    
                name="X",
                description="Form vector X",
                min=-150.0, max=150.0, default=-1)
    
    
        crackle_form_y : FloatProperty(
    
                name="Y",
                description="Form vector Y",
                min=-150.0, max=150.0, default=1)
    
    
        crackle_form_z : FloatProperty(
    
                name="Z",
                description="Form vector Z",
                min=-150.0, max=150.0, default=0)
    
    
        crackle_metric : FloatProperty(
    
                name="Metric",
                description="Crackle metric",
                min=0.0, max=150.0, default=1)
    
    
        crackle_solid : BoolProperty(
    
                name="Solid",
                description="Crackle solid",
                default=False)
    
    
        spiral_arms : FloatProperty(
    
                name="Number",
                description="",
    
                min=0.0, max=256.0, default=2.0)
    
        tiling_number : IntProperty(
    
                name="Number",
                description="",
    
                min=1, max=27, default=1)
    
        gradient_orient : EnumProperty(
    
                name="Orient",
                description="",
                items=(('x', "X", ""),
                       ('y', "Y", ""),
                       ('z', "Z", "")),
    
                default='x')
    
    
        def init(self, context):
    
            pat = self.outputs.new('PovraySocketPattern', "Pattern")
    
        def draw_buttons(self, context, layout):
    
            layout.prop(self, "pattern",text="")
            if self.pattern=='agate':
                layout.prop(self, "agate_turb")
            if self.pattern=='crackle':
                layout.prop(self, "crackle_metric")
                layout.prop(self, "crackle_solid")
    
                layout.label(text="Form:")
    
                layout.prop(self, "crackle_form_x")
                layout.prop(self, "crackle_form_y")
                layout.prop(self, "crackle_form_z")
            if self.pattern in {"spiral1","spiral2"}:
                layout.prop(self, "spiral_arms")
            if self.pattern in {'tiling'}:
                layout.prop(self, "tiling_number")
            if self.pattern in {'gradient'}:
                layout.prop(self, "gradient_orient")
        def draw_buttons_ext(self, context, layout):
            pass
    
        def draw_label(self):
            return "Other patterns"
    
    class ShaderTextureMapNode(Node, ObjectNodeTree):
        '''Texture Map'''
        bl_idname = 'ShaderTextureMapNode'
        bl_label = 'Texture map'
    
    
        brick_size_x: FloatProperty(
    
                name="X",
                description="",
    
                min=0.0000, max=1.0000, default=0.2500)
    
        brick_size_y: FloatProperty(
    
                name="Y",
                description="",
                min=0.0000, max=1.0000, default=0.0525)
    
        brick_size_z: FloatProperty(
    
                name="Z",
                description="",
    
                min=0.0000, max=1.0000, default=0.1250)
    
        brick_mortar: FloatProperty(
    
                name="Mortar",
                description="Mortar",
                min=0.000, max=1.500, default=0.01)
    
        def init(self, context):
            mat = bpy.context.object.active_material
            self.inputs.new('PovraySocketPattern', "")
            color = self.inputs.new('NodeSocketColor', "Color ramp")
            color.hide_value = True
            for i in range(0,4):
                transform=self.inputs.new('PovraySocketTransform', "Transform")
                transform.hide_value=True
            number = mat.pov.inputs_number
            for i in range(number):
                self.inputs.new('PovraySocketTexture', "%s"%i)
    
    
            self.outputs.new('PovraySocketTexture', "Texture")
    
        def draw_buttons(self, context, layout):
    
            if self.inputs[0].default_value =='brick':
                layout.prop(self, "brick_mortar")
    
                layout.label(text="Brick size:")
    
                layout.prop(self, "brick_size_x")
                layout.prop(self, "brick_size_y")
                layout.prop(self, "brick_size_z")
    
        def draw_buttons_ext(self, context, layout):
    
            if self.inputs[0].default_value =='brick':
                layout.prop(self, "brick_mortar")
    
                layout.label(text="Brick size:")
    
                layout.prop(self, "brick_size_x")
                layout.prop(self, "brick_size_y")
                layout.prop(self, "brick_size_z")
    
        def draw_label(self):
            return "Texture map"
    
    
    class ShaderNormalMapNode(Node, ObjectNodeTree):
        '''Normal Map'''
        bl_idname = 'ShaderNormalMapNode'
        bl_label = 'Normal map'
    
    
        brick_size_x : FloatProperty(
    
                name="X",
                description="",
    
                min=0.0000, max=1.0000, default=0.2500)
    
        brick_size_y : FloatProperty(
    
                name="Y",
                description="",
                min=0.0000, max=1.0000, default=0.0525)
    
        brick_size_z : FloatProperty(
    
                name="Z",
                description="",
    
                min=0.0000, max=1.0000, default=0.1250)
    
        brick_mortar : FloatProperty(
    
                name="Mortar",
                description="Mortar",
                min=0.000, max=1.500, default=0.01)
    
        def init(self, context):
            self.inputs.new('PovraySocketPattern', "")
            normal = self.inputs.new('PovraySocketFloat_10', "Normal")
            slope = self.inputs.new('PovraySocketMap', "Slope map")
            for i in range(0,4):
                transform=self.inputs.new('PovraySocketTransform', "Transform")
                transform.hide_value=True
            self.outputs.new('PovraySocketNormal', "Normal")
    
        def draw_buttons(self, context, layout):
            #for i, inp in enumerate(self.inputs):
    
            if self.inputs[0].default_value =='brick':
                layout.prop(self, "brick_mortar")
    
                layout.label(text="Brick size:")
    
                layout.prop(self, "brick_size_x")
                layout.prop(self, "brick_size_y")
                layout.prop(self, "brick_size_z")
    
        def draw_buttons_ext(self, context, layout):
    
            if self.inputs[0].default_value =='brick':
                layout.prop(self, "brick_mortar")
    
                layout.label(text="Brick size:")
    
                layout.prop(self, "brick_size_x")
                layout.prop(self, "brick_size_y")
                layout.prop(self, "brick_size_z")
    
        def draw_label(self):
            return "Normal map"
    
    class ShaderNormalMapEntryNode(Node, ObjectNodeTree):
        '''Normal Map Entry'''
        bl_idname = 'ShaderNormalMapEntryNode'
        bl_label = 'Normal map entry'
    
        def init(self, context):
            self.inputs.new('PovraySocketFloat_0_1', "Stop")
            self.inputs.new('PovraySocketFloat_0_1', "Gray")
        def draw_label(self):
            return "Normal map entry"
    
    class IsoPropsNode(Node, CompositorNodeTree):
        '''ISO Props'''
        bl_idname = 'IsoPropsNode'
        bl_label = 'Iso'
    
        node_label : StringProperty(maxlen=1024)
    
        def init(self, context):
            ob = bpy.context.object
            self.node_label = ob.name
            textName = ob.pov.function_text
            if textName:
                text = bpy.data.texts[textName]
                for line in text.lines:
                    split = line.body.split()
                    if split[0] == "#declare":
                        socket = self.inputs.new('NodeSocketFloat', "%s"%split[1])
                        value = split[3].split(";")
                        value = value[0]
                        socket.default_value=float(value)
        def draw_label(self):
            return self.node_label
    
    class PovrayFogNode(Node, CompositorNodeTree):
        '''Fog settings'''
        bl_idname = 'PovrayFogNode'
        bl_label = 'Fog'
        def init(self, context):
            color=self.inputs.new('NodeSocketColor', "Color")
            color.default_value=(0.7,0.7,0.7,0.25)
            self.inputs.new('PovraySocketFloat_0_1', "Filter")
            distance = self.inputs.new('NodeSocketInt', "Distance")
            distance.default_value=150
            self.inputs.new('NodeSocketBool', "Ground")
            fog_offset=self.inputs.new('NodeSocketFloat', "Offset")
            fog_alt=self.inputs.new('NodeSocketFloat', "Altitude")
            turb = self.inputs.new('NodeSocketVector', "Turbulence")
            turb_depth=self.inputs.new('PovraySocketFloat_0_10', "Depth")
            turb_depth.default_value=0.5
            octaves=self.inputs.new('PovraySocketInt_1_9', "Octaves")
            octaves.default_value=5
            lambdat=self.inputs.new('PovraySocketFloat_0_10', "Lambda")
            lambdat.default_value=1.25
            omega=self.inputs.new('PovraySocketFloat_0_10', "Omega")
            omega.default_value=0.35
            translate = self.inputs.new('NodeSocketVector', "Translate")
            rotate = self.inputs.new('NodeSocketVector', "Rotate")
            scale = self.inputs.new('NodeSocketVector', "Scale")
            scale.default_value=(1,1,1)
        def draw_label(self):
            return "Fog"
    
    class PovraySlopeNode(Node, TextureNodeTree):
        '''Output'''
        bl_idname = 'PovraySlopeNode'
        bl_label = 'Slope Map'
    
        def init(self, context):
            self.use_custom_color = True
            self.color = (0,0.2,0)
            slope = self.inputs.new('PovraySocketSlope', "0")
            slope = self.inputs.new('PovraySocketSlope', "1")
            slopemap = self.outputs.new('PovraySocketMap', "Slope map")
            output.hide_value = True
        def draw_buttons(self, context, layout):
    
            layout.operator("pov.nodeinputadd")
            row = layout.row()
    
            row.label(text='Value')
            row.label(text='Height')
            row.label(text='Slope')
    
    
        def draw_buttons_ext(self, context, layout):
    
            layout.operator("pov.nodeinputadd")
            row = layout.row()
    
            row.label(text='Value')
            row.label(text='Height')
            row.label(text='Slope')
    
    
        def draw_label(self):
            return "Slope Map"