-
Maurice Raybaud authored
* FIX: wrongly nested pov braces made the default outpout file fail * FIX: use agnostic metallic property rather than create a duplicate * FIX: some 2.8 deprecated properties rewired in spec;diff; emit;ambient * FIX: clean up, hierarchize and redesign Global Settings ui panel * FIX: re-wire world background alpha to agnostic prop and redo its ui * FIX: wrong nested pov braces making the default outpout file fail * FIX: use agnostic metallic property rather than create a duplicate * FIX: reduced arguments numbers by imports and relocating variables * FIX: use more list comprehesions to reduce nested conditions levels * FIX: use more consistent class names but cleanup still not finished * FIX: use single quotes for enums preferably to distinguish strings * FIX: basic level of nodes based material (diffuse color) broken API * FIX: blurry reflection corner case caused output file to fail * FIX: added context managing ("with") syntaxes reducing crash cases ___________________________________________________________ * ADD: model_all.py file to extract mostly object level loop and utils * ADD: model_meta_topology.py file to extract metaballs export * ADD: object_primitives_topology.py to extract pov compound primitives * ADD: nodes_fn.py file to extract main node exporting function * ADD: nodes_gui.py file to extract node operators and menus * ADD: nodes_properties.py file to extract nodes sub parameters * ADD: particles_properties.py to extract particles and fx parameters * ADD: render_core.py to extract main RenderEngine inheriting class(es) * ADD: shading_ray_properties.py to extract pathtraced shader parameters * ADD: texturing_procedural.py to extract algorithmic texture influences ___________________________________________________________ * UPDATE: workspace tools icons and a couple of other icons choices * RENAME: pov.add.polygontocircle.dat macro workspace tool icon * RENAME: base_ui.py to ui_core.py * RENAME: shading_nodes.py to nodes.py * RENAME: df3_library.py to voxel_lib.py to make dot lookup inform more * RENAME: object_mesh_topology.py to model_poly_topology.py * RENAME: object_curve_topology.py to model_curve_topology.py * RENAME: object_gui.py to model_gui.py * RENAME: object_primitives.py to model_primitives.py * RENAME: object_properties.py to model_properties.py * RENAME: object_particles.py to particles.py
Maurice Raybaud authored* FIX: wrongly nested pov braces made the default outpout file fail * FIX: use agnostic metallic property rather than create a duplicate * FIX: some 2.8 deprecated properties rewired in spec;diff; emit;ambient * FIX: clean up, hierarchize and redesign Global Settings ui panel * FIX: re-wire world background alpha to agnostic prop and redo its ui * FIX: wrong nested pov braces making the default outpout file fail * FIX: use agnostic metallic property rather than create a duplicate * FIX: reduced arguments numbers by imports and relocating variables * FIX: use more list comprehesions to reduce nested conditions levels * FIX: use more consistent class names but cleanup still not finished * FIX: use single quotes for enums preferably to distinguish strings * FIX: basic level of nodes based material (diffuse color) broken API * FIX: blurry reflection corner case caused output file to fail * FIX: added context managing ("with") syntaxes reducing crash cases ___________________________________________________________ * ADD: model_all.py file to extract mostly object level loop and utils * ADD: model_meta_topology.py file to extract metaballs export * ADD: object_primitives_topology.py to extract pov compound primitives * ADD: nodes_fn.py file to extract main node exporting function * ADD: nodes_gui.py file to extract node operators and menus * ADD: nodes_properties.py file to extract nodes sub parameters * ADD: particles_properties.py to extract particles and fx parameters * ADD: render_core.py to extract main RenderEngine inheriting class(es) * ADD: shading_ray_properties.py to extract pathtraced shader parameters * ADD: texturing_procedural.py to extract algorithmic texture influences ___________________________________________________________ * UPDATE: workspace tools icons and a couple of other icons choices * RENAME: pov.add.polygontocircle.dat macro workspace tool icon * RENAME: base_ui.py to ui_core.py * RENAME: shading_nodes.py to nodes.py * RENAME: df3_library.py to voxel_lib.py to make dot lookup inform more * RENAME: object_mesh_topology.py to model_poly_topology.py * RENAME: object_curve_topology.py to model_curve_topology.py * RENAME: object_gui.py to model_gui.py * RENAME: object_primitives.py to model_primitives.py * RENAME: object_properties.py to model_properties.py * RENAME: object_particles.py to particles.py
scenography_gui.py 23.76 KiB
# SPDX-License-Identifier: GPL-2.0-or-later
# <pep8 compliant>
"""User interface to camera frame, optics distortions, and environment
with world, sky, atmospheric effects such as rainbows or smoke """
import bpy
from bpy.utils import register_class, unregister_class
from bpy.types import Operator, Menu, Panel
from bl_operators.presets import AddPresetBase
from bl_ui import properties_data_camera
for member in dir(properties_data_camera):
subclass = getattr(properties_data_camera, member)
if hasattr(subclass, "COMPAT_ENGINES"):
subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
del properties_data_camera
# -------- Use only a subset of the world panels
# from bl_ui import properties_world
# # TORECREATE##DEPRECATED#properties_world.WORLD_PT_preview.COMPAT_ENGINES.add('POVRAY_RENDER')
# properties_world.WORLD_PT_context_world.COMPAT_ENGINES.add('POVRAY_RENDER')
# # TORECREATE##DEPRECATED#properties_world.WORLD_PT_world.COMPAT_ENGINES.add('POVRAY_RENDER')
# del properties_world
# -------- #
# Physics Main wrapping every class 'as is'
from bl_ui import properties_physics_common
for member in dir(properties_physics_common):
subclass = getattr(properties_physics_common, member)
if hasattr(subclass, "COMPAT_ENGINES"):
subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
del properties_physics_common
# Physics Rigid Bodies wrapping every class 'as is'
from bl_ui import properties_physics_rigidbody
for member in dir(properties_physics_rigidbody):
subclass = getattr(properties_physics_rigidbody, member)
if hasattr(subclass, "COMPAT_ENGINES"):
subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
del properties_physics_rigidbody
# Physics Rigid Body Constraint wrapping every class 'as is'
from bl_ui import properties_physics_rigidbody_constraint
for member in dir(properties_physics_rigidbody_constraint):
subclass = getattr(properties_physics_rigidbody_constraint, member)
if hasattr(subclass, "COMPAT_ENGINES"):
subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
del properties_physics_rigidbody_constraint
# Physics Smoke and fluids wrapping every class 'as is'
from bl_ui import properties_physics_fluid
for member in dir(properties_physics_fluid):
subclass = getattr(properties_physics_fluid, member)
if hasattr(subclass, "COMPAT_ENGINES"):
subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
del properties_physics_fluid
# Physics softbody wrapping every class 'as is'
from bl_ui import properties_physics_softbody
for member in dir(properties_physics_softbody):
subclass = getattr(properties_physics_softbody, member)
if hasattr(subclass, "COMPAT_ENGINES"):
subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
del properties_physics_softbody
# Physics Field wrapping every class 'as is'
from bl_ui import properties_physics_field
for member in dir(properties_physics_field):
subclass = getattr(properties_physics_field, member)
if hasattr(subclass, "COMPAT_ENGINES"):
subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
del properties_physics_field
# Physics Cloth wrapping every class 'as is'
from bl_ui import properties_physics_cloth
for member in dir(properties_physics_cloth):
subclass = getattr(properties_physics_cloth, member)
if hasattr(subclass, "COMPAT_ENGINES"):
subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
del properties_physics_cloth
# Physics Dynamic Paint wrapping every class 'as is'
from bl_ui import properties_physics_dynamicpaint
for member in dir(properties_physics_dynamicpaint):
subclass = getattr(properties_physics_dynamicpaint, member)
if hasattr(subclass, "COMPAT_ENGINES"):
subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
del properties_physics_dynamicpaint
from bl_ui import properties_particle
for member in dir(properties_particle): # add all "particle" panels from blender
subclass = getattr(properties_particle, member)
if hasattr(subclass, "COMPAT_ENGINES"):
subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
del properties_particle
class CameraDataButtonsPanel:
"""Use this class to define buttons from the camera data tab of
properties window."""
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "data"
COMPAT_ENGINES = {"POVRAY_RENDER"}
@classmethod
def poll(cls, context):
cam = context.camera
rd = context.scene.render
return cam and (rd.engine in cls.COMPAT_ENGINES)
class WorldButtonsPanel:
"""Use this class to define buttons from the world tab of
properties window."""
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "world"
COMPAT_ENGINES = {"POVRAY_RENDER"}
@classmethod
def poll(cls, context):
wld = context.world
rd = context.scene.render
return wld and (rd.engine in cls.COMPAT_ENGINES)
# ---------------------------------------------------------------- #
# Camera Settings
# ---------------------------------------------------------------- #
class CAMERA_PT_POV_cam_dof(CameraDataButtonsPanel, Panel):
"""Use this class for camera depth of field focal blur buttons."""
bl_label = "POV Aperture"
COMPAT_ENGINES = {"POVRAY_RENDER"}
bl_parent_id = "DATA_PT_camera_dof_aperture"
bl_options = {"HIDE_HEADER"}
# def draw_header(self, context):
# cam = context.camera
# self.layout.prop(cam.pov, "dof_enable", text="")
def draw(self, context):
layout = self.layout
cam = context.camera
layout.active = cam.dof.use_dof
layout.use_property_split = True # Active single-column layout
flow = layout.grid_flow(
row_major=True, columns=0, even_columns=True, even_rows=False, align=False
)
col = flow.column()
col.label(text="F-Stop value will export as")
col.label(text="POV aperture : " + "%.3f" % (1 / cam.dof.aperture_fstop * 1000))
col = flow.column()
col.prop(cam.pov, "dof_samples_min")
col.prop(cam.pov, "dof_samples_max")
col.prop(cam.pov, "dof_variance")
col.prop(cam.pov, "dof_confidence")
class CAMERA_PT_POV_cam_nor(CameraDataButtonsPanel, Panel):
"""Use this class for camera normal perturbation buttons."""
bl_label = "POV Perturbation"
COMPAT_ENGINES = {"POVRAY_RENDER"}
def draw_header(self, context):
cam = context.camera
self.layout.prop(cam.pov, "normal_enable", text="")
def draw(self, context):
layout = self.layout
cam = context.camera
layout.active = cam.pov.normal_enable
layout.prop(cam.pov, "normal_patterns")
layout.prop(cam.pov, "cam_normal")
layout.prop(cam.pov, "turbulence")
layout.prop(cam.pov, "scale")
class CAMERA_PT_POV_replacement_text(CameraDataButtonsPanel, Panel):
"""Use this class for camera text replacement field."""
bl_label = "Custom POV Code"
COMPAT_ENGINES = {"POVRAY_RENDER"}
def draw(self, context):
layout = self.layout
cam = context.camera
col = layout.column()
col.label(text="Replace properties with:")
col.prop(cam.pov, "replacement_text", text="")
# ---------------------------------------------------------------- #
# World background and sky sphere Settings
# ---------------------------------------------------------------- #
class WORLD_PT_POV_world(WorldButtonsPanel, Panel):
"""Use this class to define pov world buttons"""
bl_label = "World"
COMPAT_ENGINES = {"POVRAY_RENDER"}
def draw(self, context):
layout = self.layout
world = context.world.pov
row = layout.row(align=True)
row.menu(WORLD_MT_POV_presets.__name__, text=WORLD_MT_POV_presets.bl_label)
row.operator(WORLD_OT_POV_add_preset.bl_idname, text="", icon="ADD")
row.operator(WORLD_OT_POV_add_preset.bl_idname, text="", icon="REMOVE").remove_active = True
row = layout.row()
row.prop(world, "use_sky_paper")
row.prop(world, "use_sky_blend")
row.prop(world, "use_sky_real")
row = layout.row()
row.column().prop(world, "horizon_color")
col = row.column()
col.prop(world, "zenith_color")
col.active = world.use_sky_blend
row.column().prop(world, "ambient_color")
# row = layout.row()
# row.prop(world, "exposure") #Re-implement later as a light multiplier
# row.prop(world, "color_range")
class WORLD_PT_POV_mist(WorldButtonsPanel, Panel):
"""Use this class to define pov mist buttons."""
bl_label = "Mist"
bl_options = {"DEFAULT_CLOSED"}
COMPAT_ENGINES = {"POVRAY_RENDER"}
def draw_header(self, context):
world = context.world
self.layout.prop(world.mist_settings, "use_mist", text="")
def draw(self, context):
layout = self.layout
world = context.world
layout.active = world.mist_settings.use_mist
split = layout.split()
col = split.column()
col.prop(world.mist_settings, "intensity")
col.prop(world.mist_settings, "start")
col = split.column()
col.prop(world.mist_settings, "depth")
col.prop(world.mist_settings, "height")
layout.prop(world.mist_settings, "falloff")
class WORLD_MT_POV_presets(Menu):
"""Apply world preset to all concerned properties"""
bl_label = "World Presets"
preset_subdir = "pov/world"
preset_operator = "script.execute_preset"
draw = bpy.types.Menu.draw_preset
class WORLD_OT_POV_add_preset(AddPresetBase, Operator):
"""Add a World Preset recording current values"""
bl_idname = "object.world_preset_add"
bl_label = "Add World Preset"
preset_menu = "WORLD_MT_POV_presets"
# variable used for all preset values
preset_defines = ["scene = bpy.context.scene"]
# properties to store in the preset
preset_values = [
"scene.world.use_sky_blend",
"scene.world.horizon_color",
"scene.world.zenith_color",
"scene.world.ambient_color",
"scene.world.mist_settings.use_mist",
"scene.world.mist_settings.intensity",
"scene.world.mist_settings.depth",
"scene.world.mist_settings.start",
"scene.pov.media_enable",
"scene.pov.media_scattering_type",
"scene.pov.media_samples",
"scene.pov.media_diffusion_scale",
"scene.pov.media_diffusion_color",
"scene.pov.media_absorption_scale",
"scene.pov.media_absorption_color",
"scene.pov.media_eccentricity",
]
# where to store the preset
preset_subdir = "pov/world"
class RENDER_PT_POV_media(WorldButtonsPanel, Panel):
"""Use this class to define a pov global atmospheric media buttons."""
bl_label = "Atmosphere Media"
COMPAT_ENGINES = {"POVRAY_RENDER"}
def draw_header(self, context):
scene = context.scene
self.layout.prop(scene.pov, "media_enable", text="")
def draw(self, context):
layout = self.layout
scene = context.scene
layout.active = scene.pov.media_enable
col = layout.column()
col.prop(scene.pov, "media_scattering_type", text="")
col = layout.column()
col.prop(scene.pov, "media_samples", text="Samples")
split = layout.split()
col = split.column(align=True)
col.label(text="Scattering:")
col.prop(scene.pov, "media_diffusion_scale")
col.prop(scene.pov, "media_diffusion_color", text="")
col = split.column(align=True)
col.label(text="Absorption:")
col.prop(scene.pov, "media_absorption_scale")
col.prop(scene.pov, "media_absorption_color", text="")
if scene.pov.media_scattering_type == "5":
col = layout.column()
col.prop(scene.pov, "media_eccentricity", text="Eccentricity")
# ---------------------------------------------------------------- #
# Lights settings
# ---------------------------------------------------------------- #
# ----------------------------------------------------------------
# from bl_ui import properties_data_light
# for member in dir(properties_data_light):
# subclass = getattr(properties_data_light, member)
# try:
# subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
# except BaseException as e:
# print e.__doc__
# print('An exception occurred: {}'.format(e))
# pass
# del properties_data_light
# -------- LIGHTS -------- #
from bl_ui import properties_data_light
# -------- These panels are kept
# properties_data_light.DATA_PT_custom_props_light.COMPAT_ENGINES.add('POVRAY_RENDER')
# properties_data_light.DATA_PT_context_light.COMPAT_ENGINES.add('POVRAY_RENDER')
# make some native panels contextual to some object variable
# by recreating custom panels inheriting their properties
class PovLightButtonsPanel(properties_data_light.DataButtonsPanel):
"""Use this class to define buttons from the light data tab of
properties window."""
COMPAT_ENGINES = {"POVRAY_RENDER"}
POV_OBJECT_TYPES = {"RAINBOW"}
@classmethod
def poll(cls, context):
obj = context.object
# We use our parent class poll func too, avoids to re-define too much things...
return (
super(PovLightButtonsPanel, cls).poll(context)
and obj
and obj.pov.object_as not in cls.POV_OBJECT_TYPES
)
# We cannot inherit from RNA classes (like e.g. properties_data_mesh.DATA_PT_vertex_groups).
# Complex py/bpy/rna interactions (with metaclass and all) simply do not allow it to work.
# So we simply have to explicitly copy here the interesting bits. ;)
from bl_ui import properties_data_light
# for member in dir(properties_data_light):
# subclass = getattr(properties_data_light, member)
# try:
# subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
# except BaseException as e:
# print(e.__doc__)
# print('An exception occurred: {}'.format(e))
# pass
# Now only These panels are kept
properties_data_light.DATA_PT_custom_props_light.COMPAT_ENGINES.add("POVRAY_RENDER")
properties_data_light.DATA_PT_context_light.COMPAT_ENGINES.add("POVRAY_RENDER")
class LIGHT_PT_POV_preview(PovLightButtonsPanel, Panel):
# XXX Needs update and docstring
bl_label = properties_data_light.DATA_PT_preview.bl_label
draw = properties_data_light.DATA_PT_preview.draw
class LIGHT_PT_POV_light(PovLightButtonsPanel, Panel):
"""UI panel to main pov light parameters"""
# bl_label = properties_data_light.DATA_PT_light.bl_label
# draw = properties_data_light.DATA_PT_light.draw
# class DATA_PT_POV_light(DataButtonsPanel, Panel):
bl_label = "Light"
# COMPAT_ENGINES = {'POVRAY_RENDER'}
def draw(self, context):
layout = self.layout
light = context.light
layout.row().prop(light, "type", expand=True)
split = layout.split()
col = split.column()
sub = col.column()
sub.prop(light, "color", text="")
sub.prop(light, "energy")
if light.type in {"POINT", "SPOT"}:
sub.label(text="Falloff:")
sub.prop(light, "falloff_type", text="")
sub.prop(light, "distance")
if light.falloff_type == "LINEAR_QUADRATIC_WEIGHTED":
col.label(text="Attenuation Factors:")
sub = col.column(align=True)
sub.prop(light, "linear_attenuation", slider=True, text="Linear")
sub.prop(light, "quadratic_attenuation", slider=True, text="Quadratic")
elif light.falloff_type == "INVERSE_COEFFICIENTS":
col.label(text="Inverse Coefficients:")
sub = col.column(align=True)
sub.prop(light, "constant_coefficient", text="Constant")
sub.prop(light, "linear_coefficient", text="Linear")
sub.prop(light, "quadratic_coefficient", text="Quadratic")
if light.type == "AREA":
col.prop(light, "distance")
# restore later as interface to POV light groups ?
# col = split.column()
# col.prop(light, "use_own_layer", text="This Layer Only")
class LIGHT_MT_POV_presets(Menu):
"""Use this class to define preset menu for pov lights."""
bl_label = "Lamp Presets"
preset_subdir = "pov/light"
preset_operator = "script.execute_preset"
draw = bpy.types.Menu.draw_preset
class LIGHT_OT_POV_add_preset(AddPresetBase, Operator):
"""Operator to add a Light Preset"""
bl_idname = "object.light_preset_add"
bl_label = "Add Light Preset"
preset_menu = "LIGHT_MT_POV_presets"
# variable used for all preset values
preset_defines = ["lightdata = bpy.context.object.data"]
# properties to store in the preset
preset_values = ["lightdata.type", "lightdata.color"]
# where to store the preset
preset_subdir = "pov/light"
# Draw into the existing light panel
def light_panel_func(self, context):
"""Menu to browse and add light preset"""
layout = self.layout
row = layout.row(align=True)
row.menu(LIGHT_MT_POV_presets.__name__, text=LIGHT_MT_POV_presets.bl_label)
row.operator(LIGHT_OT_POV_add_preset.bl_idname, text="", icon="ADD")
row.operator(LIGHT_OT_POV_add_preset.bl_idname, text="", icon="REMOVE").remove_active = True
"""#TORECREATE##DEPRECATED#
class LIGHT_PT_POV_sunsky(PovLightButtonsPanel, Panel):
bl_label = properties_data_light.DATA_PT_sunsky.bl_label
@classmethod
def poll(cls, context):
lamp = context.light
engine = context.scene.render.engine
return (lamp and lamp.type == 'SUN') and (engine in cls.COMPAT_ENGINES)
draw = properties_data_light.DATA_PT_sunsky.draw
"""
class LIGHT_PT_POV_shadow(PovLightButtonsPanel, Panel):
# Todo : update and docstring
bl_label = "Shadow"
@classmethod
def poll(cls, context):
light = context.light
engine = context.scene.render.engine
return light and (engine in cls.COMPAT_ENGINES)
def draw(self, context):
layout = self.layout
light = context.light
layout.row().prop(light.pov, "shadow_method", expand=True)
split = layout.split()
col = split.column()
col.prop(light.pov, "use_halo")
sub = col.column(align=True)
sub.active = light.pov.use_halo
sub.prop(light.pov, "halo_intensity", text="Intensity")
if light.pov.shadow_method == "NOSHADOW" and light.type == "AREA":
split = layout.split()
col = split.column()
col.label(text="Form factor sampling:")
sub = col.row(align=True)
if light.shape == "SQUARE":
sub.prop(light, "shadow_ray_samples_x", text="Samples")
elif light.shape == "RECTANGLE":
sub.prop(light.pov, "shadow_ray_samples_x", text="Samples X")
sub.prop(light.pov, "shadow_ray_samples_y", text="Samples Y")
if light.pov.shadow_method != "NOSHADOW":
split = layout.split()
col = split.column()
col.prop(light, "shadow_color", text="")
# col = split.column()
# col.prop(light.pov, "use_shadow_layer", text="This Layer Only")
# col.prop(light.pov, "use_only_shadow")
if light.pov.shadow_method == "RAY_SHADOW":
split = layout.split()
col = split.column()
col.label(text="Sampling:")
if light.type in {"POINT", "SUN", "SPOT"}:
sub = col.row()
sub.prop(light.pov, "shadow_ray_samples_x", text="Samples")
# any equivalent in pov?
# sub.prop(light, "shadow_soft_size", text="Soft Size")
elif light.type == "AREA":
sub = col.row(align=True)
if light.shape == "SQUARE":
sub.prop(light.pov, "shadow_ray_samples_x", text="Samples")
elif light.shape == "RECTANGLE":
sub.prop(light.pov, "shadow_ray_samples_x", text="Samples X")
sub.prop(light.pov, "shadow_ray_samples_y", text="Samples Y")
class LIGHT_PT_POV_area(PovLightButtonsPanel, Panel):
"""Area light UI panel"""
bl_label = properties_data_light.DATA_PT_area.bl_label
bl_parent_id = "LIGHT_PT_POV_light"
bl_context = "data"
@classmethod
def poll(cls, context):
lamp = context.light
engine = context.scene.render.engine
return (lamp and lamp.type == "AREA") and (engine in cls.COMPAT_ENGINES)
draw = properties_data_light.DATA_PT_area.draw
class LIGHT_PT_POV_spot(PovLightButtonsPanel, Panel):
bl_label = properties_data_light.DATA_PT_spot.bl_label
bl_parent_id = "LIGHT_PT_POV_light"
bl_context = "data"
@classmethod
def poll(cls, context):
lamp = context.light
engine = context.scene.render.engine
return (lamp and lamp.type == "SPOT") and (engine in cls.COMPAT_ENGINES)
draw = properties_data_light.DATA_PT_spot.draw
class LIGHT_PT_POV_falloff_curve(PovLightButtonsPanel, Panel):
bl_label = properties_data_light.DATA_PT_falloff_curve.bl_label
bl_options = properties_data_light.DATA_PT_falloff_curve.bl_options
@classmethod
def poll(cls, context):
lamp = context.light
engine = context.scene.render.engine
return (
lamp and lamp.type in {"POINT", "SPOT"} and lamp.falloff_type == "CUSTOM_CURVE"
) and (engine in cls.COMPAT_ENGINES)
draw = properties_data_light.DATA_PT_falloff_curve.draw
class OBJECT_PT_POV_rainbow(PovLightButtonsPanel, Panel):
"""Use this class to define buttons from the rainbow panel of
properties window. inheriting lamp buttons panel class"""
bl_label = "POV-Ray Rainbow"
COMPAT_ENGINES = {"POVRAY_RENDER"}
# bl_options = {'HIDE_HEADER'}
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
obj = context.object
return obj and obj.pov.object_as == "RAINBOW" and (engine in cls.COMPAT_ENGINES)
def draw(self, context):
layout = self.layout
obj = context.object
col = layout.column()
if obj.pov.object_as == "RAINBOW":
if not obj.pov.unlock_parameters:
col.prop(
obj.pov, "unlock_parameters", text="Exported parameters below", icon="LOCKED"
)
col.label(text="Rainbow projection angle: " + str(obj.data.spot_size))
col.label(text="Rainbow width: " + str(obj.data.spot_blend))
col.label(text="Rainbow distance: " + str(obj.data.shadow_buffer_clip_start))
col.label(text="Rainbow arc angle: " + str(obj.pov.arc_angle))
col.label(text="Rainbow falloff angle: " + str(obj.pov.falloff_angle))
else:
col.prop(
obj.pov, "unlock_parameters", text="Edit exported parameters", icon="UNLOCKED"
)
col.label(text="3D view proxy may get out of synch")
col.active = obj.pov.unlock_parameters
layout.operator("pov.cone_update", text="Update", icon="MESH_CONE")
# col.label(text="Parameters:")
col.prop(obj.data, "spot_size", text="Rainbow Projection Angle")
col.prop(obj.data, "spot_blend", text="Rainbow width")
col.prop(obj.data, "shadow_buffer_clip_start", text="Visibility distance")
col.prop(obj.pov, "arc_angle")
col.prop(obj.pov, "falloff_angle")
del properties_data_light
classes = (
WORLD_PT_POV_world,
WORLD_MT_POV_presets,
WORLD_OT_POV_add_preset,
WORLD_PT_POV_mist,
RENDER_PT_POV_media,
LIGHT_PT_POV_preview,
LIGHT_PT_POV_light,
LIGHT_PT_POV_shadow,
LIGHT_PT_POV_spot,
LIGHT_PT_POV_area,
LIGHT_MT_POV_presets,
LIGHT_OT_POV_add_preset,
OBJECT_PT_POV_rainbow,
CAMERA_PT_POV_cam_dof,
CAMERA_PT_POV_cam_nor,
CAMERA_PT_POV_replacement_text,
)
def register():
for cls in classes:
register_class(cls)
LIGHT_PT_POV_light.prepend(light_panel_func)
def unregister():
LIGHT_PT_POV_light.remove(light_panel_func)
for cls in reversed(classes):
unregister_class(cls)