1 # SPDX-License-Identifier: GPL-2.0-or-later
3 """Declare shading properties exported to POV textures."""
5 from bpy
.utils
import register_class
, unregister_class
6 from bpy
.types
import PropertyGroup
7 from bpy
.props
import (
18 def check_material(mat
):
19 """Check that material node tree is not empty if use node button is on"""
21 return not mat
.node_tree
if mat
.use_nodes
else True
25 def pov_context_tex_datablock(context
):
26 """Texture context type recreated as deprecated in blender 2.8"""
28 idblock
= context
.brush
29 if idblock
and context
.scene
.texture_context
== "OTHER":
32 # idblock = bpy.context.active_object.active_material
33 idblock
= context
.view_layer
.objects
.active
.active_material
34 if idblock
and context
.scene
.texture_context
== "MATERIAL":
37 idblock
= context
.scene
.world
38 if idblock
and context
.scene
.texture_context
== "WORLD":
41 idblock
= context
.light
42 if idblock
and context
.scene
.texture_context
== "LIGHT":
45 if context
.particle_system
and context
.scene
.texture_context
== "PARTICLES":
46 idblock
= context
.particle_system
.settings
48 idblock
= context
.line_style
49 if idblock
and context
.scene
.texture_context
== "LINESTYLE":
55 def active_texture_name_from_uilist(self
, context
):
56 """Name created texture slots the same as created texture"""
57 idblock
= pov_context_tex_datablock(context
)
58 # mat = context.view_layer.objects.active.active_material
59 if idblock
is not None:
60 index
= idblock
.pov
.active_texture_index
61 name
= idblock
.pov_texture_slots
[index
].name
62 newname
= idblock
.pov_texture_slots
[index
].texture
63 tex
= bpy
.data
.textures
[name
]
65 idblock
.pov_texture_slots
[index
].name
= newname
68 def active_texture_name_from_search(self
, context
):
69 """Texture rolldown to change the data linked by an existing texture"""
70 idblock
= pov_context_tex_datablock(context
)
71 # mat = context.view_layer.objects.active.active_material
72 if idblock
is not None:
73 index
= idblock
.pov
.active_texture_index
74 slot
= idblock
.pov_texture_slots
[index
]
75 name
= slot
.texture_search
78 # tex = bpy.data.textures[name]
81 # Switch paint brush to this texture so settings remain contextual
82 # bpy.context.tool_settings.image_paint.brush.texture = tex
83 # bpy.context.tool_settings.image_paint.brush.mask_texture = tex
84 except BaseException
as e
:
86 print("An exception occurred: {}".format(e
))
89 def brush_texture_update(self
, context
):
91 """Brush texture rolldown must show active slot texture props"""
92 idblock
= pov_context_tex_datablock(context
)
93 if idblock
is not None:
94 # mat = context.view_layer.objects.active.active_material
95 idblock
= pov_context_tex_datablock(context
)
96 slot
= idblock
.pov_texture_slots
[idblock
.pov
.active_texture_index
]
97 if tex
:= slot
.texture
:
98 # Switch paint brush to active texture so slot and settings remain contextual
99 # bpy.ops.pov.textureslotupdate()
100 bpy
.context
.tool_settings
.image_paint
.brush
.texture
= bpy
.data
.textures
[tex
]
101 bpy
.context
.tool_settings
.image_paint
.brush
.mask_texture
= bpy
.data
.textures
[tex
]
104 class RenderPovSettingsMaterial(PropertyGroup
):
105 """Declare material level properties controllable in UI and translated to POV."""
107 # --------------------------- Begin Old Blender Internal Props --------------------------- #
108 # former Space properties from removed Blender Internal
109 use_limited_texture_context
: BoolProperty(
111 description
="Use the limited version of texture user (for ‘old shading’ mode)",
114 texture_context
: EnumProperty(
115 name
="Texture context",
116 description
="Type of texture data to display and edit",
118 ("MATERIAL", "", "Show material textures", "MATERIAL", 0), # "Show material textures"
119 ("WORLD", "", "Show world textures", "WORLD", 1), # "Show world textures"
120 ("LAMP", "", "Show lamp textures", "LIGHT", 2), # "Show lamp textures"
124 "Show particles textures",
127 ), # "Show particles textures"
131 "Show linestyle textures",
134 ), # "Show linestyle textures"
138 "Show other data textures",
141 ), # "Show other data textures"
146 active_texture_index
: IntProperty(
147 name
="Index for texture_slots", default
=0, update
=brush_texture_update
150 transparency_method
: EnumProperty(
151 name
="Specular Shader Model",
152 description
="Method to use for rendering transparency",
154 ("MASK", "Mask", "Mask the background"),
155 ("Z_TRANSPARENCY", "Z Transparency", "Use alpha buffer for transparent faces"),
156 ("RAYTRACE", "Raytrace", "Use raytracing for transparent refraction rendering"),
161 use_transparency
: BoolProperty(
162 name
="Transparency", description
="Render material as transparent", default
=False
165 alpha
: FloatProperty(
167 description
="Alpha transparency of the material",
176 specular_alpha
: FloatProperty(
177 name
="Specular alpha",
178 description
="Alpha transparency for specular areas",
187 ambient
: FloatProperty(
189 description
="Amount of global ambient color the material receives",
197 # TODO: replace by newer agnostic Material.diffuse_color and remove from pov panel
198 diffuse_color
: FloatVectorProperty(
199 name
="Diffuse color",
200 description
="Diffuse color of the material",
203 min=0, # max=inf, soft_max=1,
204 default
=(0.6, 0.6, 0.6),
205 options
={"ANIMATABLE"},
209 darkness
: FloatProperty(
211 description
="Minnaert darkness",
220 diffuse_fresnel
: FloatProperty(
221 name
="Diffuse fresnel",
222 description
="Power of Fresnel",
231 diffuse_fresnel_factor
: FloatProperty(
232 name
="Diffuse fresnel factor",
233 description
="Blending factor of Fresnel",
242 diffuse_intensity
: FloatProperty(
243 name
="Diffuse intensity",
244 description
="Amount of diffuse reflection multiplying color",
253 diffuse_ramp_blend
: EnumProperty(
254 name
="Diffuse ramp blend",
255 description
="Blending method of the ramp and the diffuse color",
259 ("MULTIPLY", "Multiply", ""),
260 ("SUBTRACT", "Subtract", ""),
261 ("SCREEN", "Screen", ""),
262 ("DIVIDE", "Divide", ""),
263 ("DIFFERENCE", "Difference", ""),
264 ("DARKEN", "Darken", ""),
265 ("LIGHTEN", "Lighten", ""),
266 ("OVERLAY", "Overlay", ""),
267 ("DODGE", "Dodge", ""),
268 ("BURN", "Burn", ""),
270 ("SATURATION", "Saturation", ""),
271 ("VALUE", "Value", ""),
272 ("COLOR", "Color", ""),
273 ("SOFT_LIGHT", "Soft light", ""),
274 ("LINEAR_LIGHT", "Linear light", ""),
279 diffuse_ramp_factor
: FloatProperty(
281 description
="Blending factor (also uses alpha in Colorband)",
290 diffuse_ramp_input
: EnumProperty(
292 description
="How the ramp maps on the surface",
294 ("SHADER", "Shader", ""),
295 ("ENERGY", "Energy", ""),
296 ("NORMAL", "Normal", ""),
297 ("RESULT", "Result", ""),
302 diffuse_shader
: EnumProperty(
303 name
="Diffuse Shader Model",
304 description
="How the ramp maps on the surface",
306 ("LAMBERT", "Lambert", "Use a Lambertian shader"),
307 ("OREN_NAYAR", "Oren-Nayar", "Use an Oren-Nayar shader"),
308 ("MINNAERT", "Minnaert", "Use a Minnaert shader"),
309 ("FRESNEL", "Fresnel", "Use a Fresnel shader"),
314 diffuse_toon_size
: FloatProperty(
316 description
="Size of diffuse toon area",
325 diffuse_toon_smooth
: FloatProperty(
327 description
="Smoothness of diffuse toon area",
338 description
="Amount of light to emit",
340 soft_min
=0.0, # max=inf, soft_max=inf,
345 mirror_color
: FloatVectorProperty(
347 description
="Mirror color of the material",
350 min=0, # max=inf, soft_max=1,
351 default
=(0.6, 0.6, 0.6),
352 options
={"ANIMATABLE"},
356 roughness
: FloatProperty(
358 description
="Oren-Nayar Roughness",
367 halo
: BoolProperty(name
="Halo", description
=" Halo settings for the material", default
=False)
368 # (was readonly in Blender2.79, never None)
370 line_color
: FloatVectorProperty(
372 description
="Line color used for Freestyle line rendering",
375 min=0, # max=inf, soft_max=1,
376 default
=(0.0, 0.0, 0.0),
377 options
={"ANIMATABLE"},
382 ## Color ramp used to affect diffuse shading
383 ## Type: ColorRamp, (readonly)
385 # cr_node = bpy.data.materials['Material'].node_tree.nodes['ColorRamp']
386 # layout.template_color_ramp(cr_node, "color_ramp", expand=True)
390 # class bpy.types.ColorRamp(bpy_struct)
392 line_priority
: IntProperty(
393 name
="Recursion Limit",
394 description
="The line color of a higher priority is used at material boundaries",
400 specular_color
: FloatVectorProperty(
401 name
="Specular color",
402 description
="Specular color of the material ",
407 default
=(1.0, 1.0, 1.0),
408 options
={"ANIMATABLE"},
411 specular_hardness
: IntProperty(
413 description
="How hard (sharp) the specular reflection is",
418 # TODO: replace by newer agnostic Material.specular_intensity and remove from pov panel
419 specular_intensity
: FloatProperty(
421 description
="How intense (bright) the specular reflection is",
430 specular_ior
: FloatProperty(
432 description
="Specular index of refraction",
443 description
="Index of refraction",
452 specular_shader
: EnumProperty(
453 name
="Specular Shader Model",
454 description
="How the ramp maps on the surface",
456 ("COOKTORR", "CookTorr", "Use a Cook-Torrance shader"),
457 ("PHONG", "Phong", "Use a Phong shader"),
458 ("BLINN", "Blinn", "Use a Blinn shader"),
459 ("TOON", "Toon", "Use a Toon shader"),
460 ("WARDISO", "WardIso", "Use a Ward anisotropic shader"),
465 specular_slope
: FloatProperty(
467 description
="The standard deviation of surface slope",
476 specular_toon_size
: FloatProperty(
478 description
="Size of specular toon area",
487 specular_toon_smooth
: FloatProperty(
489 description
="Smoothness of specular toon area",
498 translucency
: FloatProperty(
500 description
="Amount of diffuse shading on the back side",
509 transparency_method
: EnumProperty(
510 name
="Specular Shader Model",
511 description
="Method to use for rendering transparency",
513 ("MASK", "Mask", "Mask the background"),
514 ("Z_TRANSPARENCY", "Z Transparency", "Use an ior of 1 for transparent faces"),
515 ("RAYTRACE", "Raytrace", "Use raytracing for transparent refraction rendering"),
522 description
="Material type defining how the object is rendered",
524 ("SURFACE", "Surface", "Render object as a surface"),
525 # TO UPDATE > USE wire MACRO AND CHANGE DESCRIPTION
526 ("WIRE", "Wire", "Render the edges of faces as wires (not supported in raytracing)"),
527 ("VOLUME", "Volume", "Render object as a volume"),
528 # TO UPDATE > USE halo MACRO AND CHANGE DESCRIPTION
529 ("HALO", "Halo", "Render object as halo particles"),
534 use_cast_shadows
: BoolProperty(
535 name
="Cast", description
="Allow this material to cast shadows", default
=True
538 use_cast_shadows_only
: BoolProperty(
540 description
="Make objects with this material "
541 "appear invisible (not rendered), only "
546 use_cubic
: BoolProperty(
547 name
="Cubic Interpolation",
548 description
="Use cubic interpolation for diffuse " "values, for smoother transitions",
552 use_diffuse_ramp
: BoolProperty(
553 name
="Ramp", description
="Toggle diffuse ramp operations", default
=False
556 use_light_group_exclusive
: BoolProperty(
558 description
="Material uses the light group exclusively"
559 "- these lamps are excluded from other "
564 use_light_group_local
: BoolProperty(
566 description
="When linked in, material uses local light" " group with the same name",
570 use_mist
: BoolProperty(
572 description
="Use mist with this material " "(in world settings)",
576 use_nodes
: BoolProperty(
578 # Add Icon in UI or here? icon='NODES'
579 description
="Use shader nodes to render the material",
583 use_object_color
: BoolProperty(
585 description
="Modulate the result with a per-object color",
589 use_only_shadow
: BoolProperty(
591 description
="Render shadows as the material’s alpha "
592 "value, making the material transparent "
593 "except for shadowed areas",
597 use_shadeless
: BoolProperty(
599 description
="Make this material insensitive to " "light or shadow",
603 use_shadows
: BoolProperty(
604 name
="Receive", description
="Allow this material to receive shadows", default
=True
607 use_sky
: BoolProperty(
609 description
="Render this material with zero alpha, "
610 "with sky background in place (scanline only)",
614 use_specular_ramp
: BoolProperty(
615 name
="Ramp", description
="Toggle specular ramp operations", default
=False
618 use_tangent_shading
: BoolProperty(
619 name
="Tangent Shading",
620 description
="Use the material’s tangent vector instead"
621 "of the normal for shading - for "
622 "anisotropic shading effects",
626 use_transparent_shadows
: BoolProperty(
627 name
="Receive Transparent",
628 description
="Allow this object to receive transparent " "shadows cast through other object",
630 ) # linked to fake caustics
632 use_vertex_color_light
: BoolProperty(
633 name
="Vertex Color Light",
634 description
="Add vertex colors as additional lighting",
638 # TODO create interface:
639 use_vertex_color_paint
: BoolProperty(
640 name
="Vertex Color Paint",
641 description
="Replace object base color with vertex "
642 "colors (multiply with ‘texture face’ "
643 "face assigned textures)",
647 specular_ramp_blend
: EnumProperty(
648 name
="Specular ramp blend",
649 description
="Blending method of the ramp and the specular color",
653 ("MULTIPLY", "Multiply", ""),
654 ("SUBTRACT", "Subtract", ""),
655 ("SCREEN", "Screen", ""),
656 ("DIVIDE", "Divide", ""),
657 ("DIFFERENCE", "Difference", ""),
658 ("DARKEN", "Darken", ""),
659 ("LIGHTEN", "Lighten", ""),
660 ("OVERLAY", "Overlay", ""),
661 ("DODGE", "Dodge", ""),
662 ("BURN", "Burn", ""),
664 ("SATURATION", "Saturation", ""),
665 ("VALUE", "Value", ""),
666 ("COLOR", "Color", ""),
667 ("SOFT_LIGHT", "Soft light", ""),
668 ("LINEAR_LIGHT", "Linear light", ""),
673 specular_ramp_factor
: FloatProperty(
675 description
="Blending factor (also uses alpha in Colorband)",
684 specular_ramp_input
: EnumProperty(
686 description
="How the ramp maps on the surface",
688 ("SHADER", "Shader", ""),
689 ("ENERGY", "Energy", ""),
690 ("NORMAL", "Normal", ""),
691 ("RESULT", "Result", ""),
696 irid_enable
: BoolProperty(
697 name
="Iridescence coating",
698 description
="Newton's thin film interference (like an oil slick on a puddle of "
699 "water or the rainbow hues of a soap bubble.)",
703 mirror_use_IOR
: BoolProperty(
704 name
="Correct Reflection",
705 description
="Use same IOR as raytrace transparency to calculate mirror reflections. "
706 "More physically correct",
710 conserve_energy
: BoolProperty(
711 name
="Conserve Energy",
712 description
="Light transmitted is more correctly reduced by mirror reflections, "
713 "also the sum of diffuse and translucency gets reduced below one ",
717 irid_amount
: FloatProperty(
719 description
="Contribution of the iridescence effect to the overall surface color. "
720 "As a rule of thumb keep to around 0.25 (25% contribution) or less, "
721 "but experiment. If the surface is coming out too white, try lowering "
722 "the diffuse and possibly the ambient values of the surface",
730 irid_thickness
: FloatProperty(
732 description
="A very thin film will have a high frequency of color changes while a "
733 "thick film will have large areas of color",
741 irid_turbulence
: FloatProperty(
743 description
="This parameter varies the thickness",
751 interior_fade_color
: FloatVectorProperty(
752 name
="Interior Fade Color",
753 description
="Color of filtered attenuation for transparent " "materials",
759 options
={"ANIMATABLE"},
763 caustics_enable
: BoolProperty(
765 description
="use only fake refractive caustics (default) or photon based "
766 "reflective/refractive caustics",
770 fake_caustics
: BoolProperty(
771 name
="Fake Caustics",
772 description
="use only (Fast) fake refractive caustics based on transparent shadows",
776 fake_caustics_power
: FloatProperty(
777 name
="Fake caustics power",
778 description
="Values typically range from 0.0 to 1.0 or higher. Zero is no caustics. "
779 "Low, non-zero values give broad hot-spots while higher values give "
780 "tighter, smaller simulated focal points",
788 refraction_caustics
: BoolProperty(
789 name
="Refractive Caustics",
790 description
="hotspots of light focused when going through the material",
794 photons_dispersion
: FloatProperty(
795 name
="Chromatic Dispersion",
796 description
="Light passing through will be separated according to wavelength. "
797 "This ratio of refractive indices for violet to red controls how much "
798 "the colors are spread out 1 = no dispersion, good values are 1.01 to 1.1",
807 photons_dispersion_samples
: IntProperty(
808 name
="Dispersion Samples",
809 description
="Number of color-steps for dispersion",
815 photons_reflection
: BoolProperty(
816 name
="Reflective Photon Caustics",
817 description
="Use this to make your Sauron's ring ;-P",
821 refraction_type
: EnumProperty(
823 ("1", "Z Transparency Fake Caustics", "use fake caustics"),
824 ("2", "Raytrace Photons Caustics", "use photons for refractive caustics"),
826 name
="Refraction Type:",
827 description
="use fake caustics (fast) or true photons for refractive Caustics",
831 # ------------------------------ CustomPOV Code ------------------------------ #
832 replacement_text
: StringProperty(
833 name
="Declared name:",
834 description
="Type the variable name as declared either directly inlined "
835 "in your custom POV code from the text editor datablock (checked as a "
836 "source to render in it's side property panel), or this declaration can be "
837 "from an external .inc it points at. Here, name = texture {} expected",
843 def use_material_nodes_callback(self
, context
):
844 """Identify if node has been added and if it is used yet or default"""
846 if hasattr(context
.space_data
, "tree_type"):
847 context
.space_data
.tree_type
= "ObjectNodeTree"
848 mat
= context
.object.active_material
849 if mat
.pov
.material_use_nodes
:
852 # tree.name = mat.name # XXX READONLY
855 if len(tree
.nodes
) == 2:
858 for node
in tree
.nodes
:
859 if node
.type in {"OUTPUT", "MATERIAL"}:
860 tree
.nodes
.remove(node
)
862 for node
in tree
.nodes
:
863 if node
.bl_idname
== "PovrayOutputNode":
865 elif node
.bl_idname
== "PovrayTextureNode":
867 if o
== 1 and m
== 1:
869 elif len(tree
.nodes
) == 0:
874 output
= tree
.nodes
.new("PovrayOutputNode")
875 output
.location
= 200, 200
876 tmap
= tree
.nodes
.new("PovrayTextureNode")
877 tmap
.location
= 0, 200
878 links
.new(tmap
.outputs
[0], output
.inputs
[0])
880 tree
.nodes
.active
= tmap
882 mat
.use_nodes
= False
884 def use_texture_nodes_callback(self
, context
):
885 """Identify texture nodes by filtering out output and composite ones"""
887 tex
= context
.object.active_material
.active_texture
888 if tex
.pov
.texture_use_nodes
:
890 if len(tex
.node_tree
.nodes
) == 2:
891 for node
in tex
.node_tree
.nodes
:
892 if node
.type in {"OUTPUT", "CHECKER"}:
893 tex
.node_tree
.nodes
.remove(node
)
895 tex
.use_nodes
= False
897 def node_active_callback(self
, context
):
898 """Synchronize active node with material before getting it"""
900 items
= [] # XXX comment out > remove?
901 mat
= context
.material
902 mat
.node_tree
.nodes
# XXX comment out > remove?
903 for node
in mat
.node_tree
.nodes
:
905 for node
in mat
.node_tree
.nodes
:
906 if node
.name
== mat
.pov
.material_active_node
:
908 mat
.node_tree
.nodes
.active
= node
912 def node_enum_callback(self
, context
):
913 mat
= context
.material
914 nodes
= mat
.node_tree
.nodes
915 return [("%s" % node
.name
, "%s" % node
.name
, "") for node
in nodes
]
917 def pigment_normal_callback(self
, context
):
918 render
= context
.scene
.pov
.render
# XXX comment out > remove?
920 [("pigment", "Pigment", ""), ("normal", "Normal", "")]
921 # XXX Find any other such traces of hgpovray experiment > remove or deploy ?
922 if render
!= "hgpovray"
924 ("pigment", "Pigment", ""),
925 ("normal", "Normal", ""),
926 ("modulation", "Modulation", ""),
930 def glow_callback(self
, context
):
931 scene
= context
.scene
933 ob
.pov
.mesh_write_as_old
= ob
.pov
.mesh_write_as
934 if scene
.pov
.render
== "uberpov" and ob
.pov
.glow
:
935 ob
.pov
.mesh_write_as
= "NONE"
937 ob
.pov
.mesh_write_as
= ob
.pov
.mesh_write_as_old
939 material_use_nodes
: BoolProperty(
940 name
="Use nodes", description
="", update
=use_material_nodes_callback
, default
=False
943 material_active_node
: EnumProperty(
944 name
="Active node", description
="", items
=node_enum_callback
, update
=node_active_callback
947 preview_settings
: BoolProperty(name
="Preview Settings", description
="", default
=False)
949 object_preview_transform
: BoolProperty(name
="Transform object", description
="", default
=False)
951 object_preview_scale
: FloatProperty(name
="XYZ", min=0.5, max=2.0, default
=1.0)
953 object_preview_rotate
: FloatVectorProperty(
954 name
="Rotate", description
="", min=-180.0, max=180.0, default
=(0.0, 0.0, 0.0), subtype
="XYZ"
957 object_preview_bgcontrast
: FloatProperty(name
="Contrast", min=0.0, max=1.0, default
=0.5)
961 # ------------------------------ End Old Blender Internal Props ------------------------------ #
965 RenderPovSettingsMaterial
,
973 bpy
.types
.Material
.pov
= PointerProperty(type=RenderPovSettingsMaterial
)
977 del bpy
.types
.Material
.pov
979 for cls
in reversed(classes
):
980 unregister_class(cls
)