Skip to content
Snippets Groups Projects
shading_properties.py 29.8 KiB
Newer Older
  • Learn to ignore specific revisions
  • # SPDX-License-Identifier: GPL-2.0-or-later
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
    """Declare shading properties exported to POV textures."""
    import bpy
    from bpy.utils import register_class, unregister_class
    from bpy.types import PropertyGroup
    from bpy.props import (
        FloatVectorProperty,
        StringProperty,
        BoolProperty,
        IntProperty,
        FloatProperty,
        EnumProperty,
        PointerProperty,
    )
    
    
    def check_material(mat):
        """Check that material node tree is not empty if use node button is on"""
        if mat is not None:
    
            return not mat.node_tree if mat.use_nodes else True
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        return False
    
    
    def pov_context_tex_datablock(context):
        """Texture context type recreated as deprecated in blender 2.8"""
    
        idblock = context.brush
    
        if idblock and context.scene.texture_context == "OTHER":
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            return idblock
    
        # idblock = bpy.context.active_object.active_material
        idblock = context.view_layer.objects.active.active_material
    
        if idblock and context.scene.texture_context == "MATERIAL":
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            return idblock
    
        idblock = context.scene.world
    
        if idblock and context.scene.texture_context == "WORLD":
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            return idblock
    
        idblock = context.light
    
        if idblock and context.scene.texture_context == "LIGHT":
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            return idblock
    
    
        if context.particle_system and context.scene.texture_context == "PARTICLES":
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            idblock = context.particle_system.settings
    
        idblock = context.line_style
    
        if idblock and context.scene.texture_context == "LINESTYLE":
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            return idblock
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
    def active_texture_name_from_uilist(self, context):
        """Name created texture slots the same as created texture"""
        idblock = pov_context_tex_datablock(context)
        # mat = context.view_layer.objects.active.active_material
        if idblock is not None:
            index = idblock.pov.active_texture_index
            name = idblock.pov_texture_slots[index].name
            newname = idblock.pov_texture_slots[index].texture
            tex = bpy.data.textures[name]
            tex.name = newname
            idblock.pov_texture_slots[index].name = newname
    
    
    def active_texture_name_from_search(self, context):
        """Texture rolldown to change the data linked by an existing texture"""
        idblock = pov_context_tex_datablock(context)
        # mat = context.view_layer.objects.active.active_material
        if idblock is not None:
            index = idblock.pov.active_texture_index
            slot = idblock.pov_texture_slots[index]
            name = slot.texture_search
    
        try:
            # tex = bpy.data.textures[name]
            slot.name = name
            slot.texture = name
            # Switch paint brush to this texture so settings remain contextual
            # bpy.context.tool_settings.image_paint.brush.texture = tex
            # bpy.context.tool_settings.image_paint.brush.mask_texture = tex
        except BaseException as e:
            print(e.__doc__)
    
            print("An exception occurred: {}".format(e))
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
    
    def brush_texture_update(self, context):
    
        """Brush texture rolldown must show active slot texture props"""
        idblock = pov_context_tex_datablock(context)
        if idblock is not None:
            # mat = context.view_layer.objects.active.active_material
            idblock = pov_context_tex_datablock(context)
            slot = idblock.pov_texture_slots[idblock.pov.active_texture_index]
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                # Switch paint brush to active texture so slot and settings remain contextual
    
                # bpy.ops.pov.textureslotupdate()
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                bpy.context.tool_settings.image_paint.brush.texture = bpy.data.textures[tex]
                bpy.context.tool_settings.image_paint.brush.mask_texture = bpy.data.textures[tex]
    
    
    class RenderPovSettingsMaterial(PropertyGroup):
        """Declare material level properties controllable in UI and translated to POV."""
    
    
        # --------------------------- Begin Old Blender Internal Props --------------------------- #
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        # former Space properties from  removed Blender Internal
        use_limited_texture_context: BoolProperty(
            name="",
            description="Use the limited version of texture user (for ‘old shading’ mode)",
            default=True,
        )
        texture_context: EnumProperty(
            name="Texture context",
            description="Type of texture data to display and edit",
            items=(
                ("MATERIAL", "", "Show material textures", "MATERIAL", 0),  # "Show material textures"
                ("WORLD", "", "Show world textures", "WORLD", 1),  # "Show world textures"
                ("LAMP", "", "Show lamp textures", "LIGHT", 2),  # "Show lamp textures"
                (
                    "PARTICLES",
                    "",
                    "Show particles textures",
                    "PARTICLES",
                    3,
                ),  # "Show particles textures"
                (
                    "LINESTYLE",
                    "",
                    "Show linestyle textures",
                    "LINE_DATA",
                    4,
                ),  # "Show linestyle textures"
                (
                    "OTHER",
                    "",
                    "Show other data textures",
                    "TEXTURE_DATA",
                    5,
                ),  # "Show other data textures"
            ),
            default="MATERIAL",
        )
    
        active_texture_index: IntProperty(
            name="Index for texture_slots", default=0, update=brush_texture_update
        )
    
        transparency_method: EnumProperty(
            name="Specular Shader Model",
            description="Method to use for rendering transparency",
            items=(
                ("MASK", "Mask", "Mask the background"),
                ("Z_TRANSPARENCY", "Z Transparency", "Use alpha buffer for transparent faces"),
                ("RAYTRACE", "Raytrace", "Use raytracing for transparent refraction rendering"),
            ),
            default="MASK",
        )
    
        use_transparency: BoolProperty(
            name="Transparency", description="Render material as transparent", default=False
        )
    
        alpha: FloatProperty(
            name="Alpha",
            description="Alpha transparency of the material",
            min=0.0,
            max=1.0,
            soft_min=0.0,
            soft_max=1.0,
            default=1.0,
            precision=3,
        )
    
        specular_alpha: FloatProperty(
            name="Specular alpha",
            description="Alpha transparency for specular areas",
            min=0.0,
            max=1.0,
            soft_min=0.0,
            soft_max=1.0,
            default=1.0,
            precision=3,
        )
    
        ambient: FloatProperty(
            name="Ambient",
            description="Amount of global ambient color the material receives",
            min=0.0,
            max=1.0,
            soft_min=0.0,
            soft_max=1.0,
            default=1.0,
            precision=3,
        )
    
        # TODO: replace by newer agnostic Material.diffuse_color and remove from pov panel
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        diffuse_color: FloatVectorProperty(
            name="Diffuse color",
    
            description="Diffuse color of the material",
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            precision=4,
            step=0.01,
            min=0,  # max=inf, soft_max=1,
            default=(0.6, 0.6, 0.6),
            options={"ANIMATABLE"},
            subtype="COLOR",
        )
    
        darkness: FloatProperty(
            name="Darkness",
            description="Minnaert darkness",
            min=0.0,
            max=2.0,
            soft_min=0.0,
            soft_max=2.0,
            default=1.0,
            precision=3,
        )
    
        diffuse_fresnel: FloatProperty(
            name="Diffuse fresnel",
            description="Power of Fresnel",
            min=0.0,
            max=5.0,
            soft_min=0.0,
            soft_max=5.0,
            default=1.0,
            precision=3,
        )
    
        diffuse_fresnel_factor: FloatProperty(
            name="Diffuse fresnel factor",
            description="Blending factor of Fresnel",
            min=0.0,
            max=5.0,
            soft_min=0.0,
            soft_max=5.0,
            default=0.5,
            precision=3,
        )
    
        diffuse_intensity: FloatProperty(
            name="Diffuse intensity",
            description="Amount of diffuse reflection multiplying color",
            min=0.0,
            max=1.0,
            soft_min=0.0,
            soft_max=1.0,
            default=0.8,
            precision=3,
        )
    
        diffuse_ramp_blend: EnumProperty(
            name="Diffuse ramp blend",
            description="Blending method of the ramp and the diffuse color",
            items=(
                ("MIX", "Mix", ""),
                ("ADD", "Add", ""),
                ("MULTIPLY", "Multiply", ""),
                ("SUBTRACT", "Subtract", ""),
                ("SCREEN", "Screen", ""),
                ("DIVIDE", "Divide", ""),
                ("DIFFERENCE", "Difference", ""),
                ("DARKEN", "Darken", ""),
                ("LIGHTEN", "Lighten", ""),
                ("OVERLAY", "Overlay", ""),
                ("DODGE", "Dodge", ""),
                ("BURN", "Burn", ""),
                ("HUE", "Hue", ""),
                ("SATURATION", "Saturation", ""),
                ("VALUE", "Value", ""),
                ("COLOR", "Color", ""),
                ("SOFT_LIGHT", "Soft light", ""),
                ("LINEAR_LIGHT", "Linear light", ""),
            ),
            default="MIX",
        )
    
        diffuse_ramp_factor: FloatProperty(
            name="Factor",
            description="Blending factor (also uses alpha in Colorband)",
            min=0.0,
            max=1.0,
            soft_min=0.0,
            soft_max=1.0,
            default=1.0,
            precision=3,
        )
    
        diffuse_ramp_input: EnumProperty(
            name="Input",
            description="How the ramp maps on the surface",
            items=(
                ("SHADER", "Shader", ""),
                ("ENERGY", "Energy", ""),
                ("NORMAL", "Normal", ""),
                ("RESULT", "Result", ""),
            ),
            default="SHADER",
        )
    
        diffuse_shader: EnumProperty(
            name="Diffuse Shader Model",
            description="How the ramp maps on the surface",
            items=(
                ("LAMBERT", "Lambert", "Use a Lambertian shader"),
                ("OREN_NAYAR", "Oren-Nayar", "Use an Oren-Nayar shader"),
                ("MINNAERT", "Minnaert", "Use a Minnaert shader"),
                ("FRESNEL", "Fresnel", "Use a Fresnel shader"),
            ),
            default="LAMBERT",
        )
    
        diffuse_toon_size: FloatProperty(
            name="Size",
            description="Size of diffuse toon area",
            min=0.0,
            max=3.14,
            soft_min=0.0,
            soft_max=3.14,
            default=0.5,
            precision=3,
        )
    
        diffuse_toon_smooth: FloatProperty(
            name="Smooth",
            description="Smoothness of diffuse toon area",
            min=0.0,
            max=1.0,
            soft_min=0.0,
            soft_max=1.0,
            default=0.1,
            precision=3,
        )
    
        emit: FloatProperty(
            name="Emit",
            description="Amount of light to emit",
            min=0.0,
            soft_min=0.0,  # max=inf, soft_max=inf,
            default=0.0,
            precision=3,
        )
    
        mirror_color: FloatVectorProperty(
            name="Mirror color",
    
            description="Mirror color of the material",
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            precision=4,
            step=0.01,
            min=0,  # max=inf, soft_max=1,
            default=(0.6, 0.6, 0.6),
            options={"ANIMATABLE"},
            subtype="COLOR",
        )
    
        roughness: FloatProperty(
            name="Roughness",
            description="Oren-Nayar Roughness",
            min=0.0,
            max=3.14,
            soft_min=0.0,
            soft_max=3.14,
            precision=3,
            default=0.5,
        )
    
        halo: BoolProperty(name="Halo", description=" Halo settings for the material", default=False)
        # (was readonly in Blender2.79, never None)
    
        line_color: FloatVectorProperty(
            name="Line color",
    
            description="Line color used for Freestyle line rendering",
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            precision=4,
            step=0.01,
            min=0,  # max=inf, soft_max=1,
            default=(0.0, 0.0, 0.0),
            options={"ANIMATABLE"},
            subtype="COLOR",
        )
    
        # diffuse_ramp:
        ## Color ramp used to affect diffuse shading
        ## Type:    ColorRamp, (readonly)
    
        # cr_node = bpy.data.materials['Material'].node_tree.nodes['ColorRamp']
        # layout.template_color_ramp(cr_node, "color_ramp", expand=True)
    
        # ou
    
        # class bpy.types.ColorRamp(bpy_struct)
    
        line_priority: IntProperty(
            name="Recursion Limit",
            description="The line color of a higher priority is used at material boundaries",
            min=0,
            max=32767,
            default=0,
        )
    
        specular_color: FloatVectorProperty(
            name="Specular color",
    
            description="Specular color of the material ",
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            precision=4,
            step=0.01,
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            default=(1.0, 1.0, 1.0),
            options={"ANIMATABLE"},
            subtype="COLOR",
        )
        specular_hardness: IntProperty(
            name="Hardness",
            description="How hard (sharp) the specular reflection is",
            min=1,
            max=511,
            default=30,
        )
    
        # TODO: replace by newer agnostic Material.specular_intensity and remove from pov panel
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        specular_intensity: FloatProperty(
            name="Intensity",
            description="How intense (bright) the specular reflection is",
            min=0.0,
            max=1.0,
            soft_min=0.0,
            soft_max=1.0,
            default=0.1,
            precision=3,
        )
    
        specular_ior: FloatProperty(
            name="IOR",
            description="Specular index of refraction",
            min=-10.0,
            max=10.0,
            soft_min=0.0,
            soft_max=10.0,
            default=1.0,
            precision=3,
        )
    
        ior: FloatProperty(
            name="IOR",
            description="Index of refraction",
            min=-10.0,
            max=10.0,
            soft_min=0.0,
            soft_max=10.0,
            default=1.0,
            precision=3,
        )
    
        specular_shader: EnumProperty(
            name="Specular Shader Model",
            description="How the ramp maps on the surface",
            items=(
                ("COOKTORR", "CookTorr", "Use a Cook-Torrance shader"),
                ("PHONG", "Phong", "Use a Phong shader"),
                ("BLINN", "Blinn", "Use a Blinn shader"),
                ("TOON", "Toon", "Use a Toon shader"),
                ("WARDISO", "WardIso", "Use a Ward anisotropic shader"),
            ),
            default="COOKTORR",
        )
    
        specular_slope: FloatProperty(
            name="Slope",
            description="The standard deviation of surface slope",
            min=0.0,
            max=0.4,
            soft_min=0.0,
            soft_max=0.4,
            default=0.1,
            precision=3,
        )
    
        specular_toon_size: FloatProperty(
            name="Size",
            description="Size of specular toon area",
            min=0.0,
            max=0.53,
            soft_min=0.0,
            soft_max=0.53,
            default=0.5,
            precision=3,
        )
    
        specular_toon_smooth: FloatProperty(
            name="Smooth",
            description="Smoothness of specular toon area",
            min=0.0,
            max=1.0,
            soft_min=0.0,
            soft_max=1.0,
            default=0.1,
            precision=3,
        )
    
        translucency: FloatProperty(
            name="Translucency",
            description="Amount of diffuse shading on the back side",
            min=0.0,
            max=1.0,
            soft_min=0.0,
            soft_max=1.0,
            default=0.0,
            precision=3,
        )
    
        transparency_method: EnumProperty(
            name="Specular Shader Model",
            description="Method to use for rendering transparency",
            items=(
                ("MASK", "Mask", "Mask the background"),
                ("Z_TRANSPARENCY", "Z Transparency", "Use an ior of 1 for transparent faces"),
                ("RAYTRACE", "Raytrace", "Use raytracing for transparent refraction rendering"),
            ),
            default="MASK",
        )
    
        type: EnumProperty(
            name="Type",
            description="Material type defining how the object is rendered",
            items=(
                ("SURFACE", "Surface", "Render object as a surface"),
                # TO UPDATE > USE wire MACRO AND CHANGE DESCRIPTION
                ("WIRE", "Wire", "Render the edges of faces as wires (not supported in raytracing)"),
                ("VOLUME", "Volume", "Render object as a volume"),
                # TO UPDATE > USE halo MACRO AND CHANGE DESCRIPTION
                ("HALO", "Halo", "Render object as halo particles"),
            ),
            default="SURFACE",
        )
    
        use_cast_shadows: BoolProperty(
            name="Cast", description="Allow this material to cast shadows", default=True
        )
    
        use_cast_shadows_only: BoolProperty(
            name="Cast Only",
            description="Make objects with this material "
            "appear invisible (not rendered), only "
            "casting shadows",
            default=False,
        )
    
        use_cubic: BoolProperty(
            name="Cubic Interpolation",
            description="Use cubic interpolation for diffuse " "values, for smoother transitions",
            default=False,
        )
    
        use_diffuse_ramp: BoolProperty(
            name="Ramp", description="Toggle diffuse ramp operations", default=False
        )
    
        use_light_group_exclusive: BoolProperty(
            name="Exclusive",
            description="Material uses the light group exclusively"
            "- these lamps are excluded from other "
            "scene lighting",
            default=False,
        )
    
        use_light_group_local: BoolProperty(
            name="Local",
            description="When linked in, material uses local light" " group with the same name",
            default=False,
        )
    
        use_mist: BoolProperty(
            name="Use Mist",
            description="Use mist with this material " "(in world settings)",
            default=True,
        )
    
        use_nodes: BoolProperty(
            name="Nodes",
            # Add Icon in UI or here? icon='NODES'
            description="Use shader nodes to render the material",
            default=False,
        )
    
        use_object_color: BoolProperty(
            name="Object Color",
            description="Modulate the result with a per-object color",
            default=False,
        )
    
        use_only_shadow: BoolProperty(
            name="Shadows Only",
            description="Render shadows as the material’s alpha "
            "value, making the material transparent "
            "except for shadowed areas",
            default=False,
        )
    
        use_shadeless: BoolProperty(
            name="Shadeless",
            description="Make this material insensitive to " "light or shadow",
            default=False,
        )
    
        use_shadows: BoolProperty(
            name="Receive", description="Allow this material to receive shadows", default=True
        )
    
        use_sky: BoolProperty(
            name="Sky",
            description="Render this material with zero alpha, "
            "with sky background in place (scanline only)",
            default=False,
        )
    
        use_specular_ramp: BoolProperty(
            name="Ramp", description="Toggle specular ramp operations", default=False
        )
    
        use_tangent_shading: BoolProperty(
            name="Tangent Shading",
            description="Use the material’s tangent vector instead"
            "of the normal for shading - for "
            "anisotropic shading effects",
            default=False,
        )
    
        use_transparent_shadows: BoolProperty(
            name="Receive Transparent",
            description="Allow this object to receive transparent " "shadows cast through other object",
            default=False,
        )  # linked to fake caustics
    
        use_vertex_color_light: BoolProperty(
            name="Vertex Color Light",
            description="Add vertex colors as additional lighting",
            default=False,
        )
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        use_vertex_color_paint: BoolProperty(
            name="Vertex Color Paint",
            description="Replace object base color with vertex "
            "colors (multiply with ‘texture face’ "
            "face assigned textures)",
            default=False,
        )
    
        specular_ramp_blend: EnumProperty(
            name="Specular ramp blend",
            description="Blending method of the ramp and the specular color",
            items=(
                ("MIX", "Mix", ""),
                ("ADD", "Add", ""),
                ("MULTIPLY", "Multiply", ""),
                ("SUBTRACT", "Subtract", ""),
                ("SCREEN", "Screen", ""),
                ("DIVIDE", "Divide", ""),
                ("DIFFERENCE", "Difference", ""),
                ("DARKEN", "Darken", ""),
                ("LIGHTEN", "Lighten", ""),
                ("OVERLAY", "Overlay", ""),
                ("DODGE", "Dodge", ""),
                ("BURN", "Burn", ""),
                ("HUE", "Hue", ""),
                ("SATURATION", "Saturation", ""),
                ("VALUE", "Value", ""),
                ("COLOR", "Color", ""),
                ("SOFT_LIGHT", "Soft light", ""),
                ("LINEAR_LIGHT", "Linear light", ""),
            ),
            default="MIX",
        )
    
        specular_ramp_factor: FloatProperty(
            name="Factor",
            description="Blending factor (also uses alpha in Colorband)",
            min=0.0,
            max=1.0,
            soft_min=0.0,
            soft_max=1.0,
            default=1.0,
            precision=3,
        )
    
        specular_ramp_input: EnumProperty(
            name="Input",
            description="How the ramp maps on the surface",
            items=(
                ("SHADER", "Shader", ""),
                ("ENERGY", "Energy", ""),
                ("NORMAL", "Normal", ""),
                ("RESULT", "Result", ""),
            ),
            default="SHADER",
        )
    
        irid_enable: BoolProperty(
            name="Iridescence coating",
            description="Newton's thin film interference (like an oil slick on a puddle of "
            "water or the rainbow hues of a soap bubble.)",
            default=False,
        )
    
        mirror_use_IOR: BoolProperty(
            name="Correct Reflection",
            description="Use same IOR as raytrace transparency to calculate mirror reflections. "
            "More physically correct",
            default=False,
        )
    
        conserve_energy: BoolProperty(
            name="Conserve Energy",
            description="Light transmitted is more correctly reduced by mirror reflections, "
            "also the sum of diffuse and translucency gets reduced below one ",
            default=True,
        )
    
        irid_amount: FloatProperty(
            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",
            min=0.0,
            max=1.0,
            soft_min=0.01,
            soft_max=1.0,
            default=0.25,
        )
    
        irid_thickness: FloatProperty(
            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",
            min=0.0,
            max=1000.0,
            soft_min=0.1,
            soft_max=10.0,
            default=1,
        )
    
        irid_turbulence: FloatProperty(
            name="turbulence",
            description="This parameter varies the thickness",
            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 " "materials",
            precision=4,
            step=0.01,
            min=0.0,
            soft_max=1.0,
            default=(0, 0, 0),
            options={"ANIMATABLE"},
            subtype="COLOR",
        )
    
        caustics_enable: BoolProperty(
            name="Caustics",
            description="use only fake refractive caustics (default) or photon based "
            "reflective/refractive caustics",
            default=True,
        )
    
        fake_caustics: BoolProperty(
    
            name="Fake Caustics",
            description="use only (Fast) fake refractive caustics based on transparent shadows",
            default=True
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        )
    
        fake_caustics_power: FloatProperty(
            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.15,
        )
    
        refraction_caustics: BoolProperty(
            name="Refractive Caustics",
            description="hotspots of light focused when going through the material",
            default=True,
        )
    
        photons_dispersion: FloatProperty(
            name="Chromatic Dispersion",
            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,
        )
    
        photons_reflection: BoolProperty(
            name="Reflective Photon Caustics",
            description="Use this to make your Sauron's ring ;-P",
            default=False,
        )
    
        refraction_type: EnumProperty(
            items=[
                ("1", "Z Transparency Fake Caustics", "use fake caustics"),
                ("2", "Raytrace Photons Caustics", "use photons for refractive caustics"),
            ],
            name="Refraction Type:",
            description="use fake caustics (fast) or true photons for refractive Caustics",
            default="1",
        )
    
    
        # ------------------------------ CustomPOV Code ------------------------------ #
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        replacement_text: StringProperty(
            name="Declared name:",
            description="Type the variable name as declared either directly inlined "
            "in your custom POV code from the text editor datablock (checked as a "
            "source to render in it's side property panel), or this declaration can be "
            "from an external .inc it points at. Here, name = texture {} expected",
            default="",
        )
    
        # NODES
    
        def use_material_nodes_callback(self, context):
            """Identify if node has been added and if it is used yet or default"""
    
            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 # XXX READONLY
                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
    
                        elif node.bl_idname == "PovrayTextureNode":
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                            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):
            """Identify texture nodes by filtering out output and composite ones"""
    
            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):
            """Synchronize active node with material before getting it"""
    
            items = []  # XXX comment out > remove?
            mat = context.material
            mat.node_tree.nodes  # XXX comment out > remove?
            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):
            mat = context.material
            nodes = mat.node_tree.nodes
    
            return [("%s" % node.name, "%s" % node.name, "") for node in nodes]
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
        def pigment_normal_callback(self, context):
            render = context.scene.pov.render  # XXX comment out > remove?
    
            return (
                [("pigment", "Pigment", ""), ("normal", "Normal", "")]
                # XXX Find any other such traces of hgpovray experiment > remove or deploy ?
                if render != "hgpovray"
                else [
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    ("pigment", "Pigment", ""),
                    ("normal", "Normal", ""),
                    ("modulation", "Modulation", ""),
                ]
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
        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)
    
    
    
    
    # ------------------------------ End Old Blender Internal Props ------------------------------ #
    
    classes = (
        RenderPovSettingsMaterial,
    )
    
    def register():
        for cls in classes:
            register_class(cls)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
        bpy.types.Material.pov = PointerProperty(type=RenderPovSettingsMaterial)
    
    
    def unregister():
        del bpy.types.Material.pov
    
        for cls in reversed(classes):
            unregister_class(cls)