Sun Position: update HDRI mode shader for Metal compatibility
[blender-addons.git] / render_povray / scenography_gui.py
blobd8a0298437532d577f34711b2951a66ca184c391
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 """User interface to camera frame, optics distortions, and environment
5 with world, sky, atmospheric effects such as rainbows or smoke """
7 import bpy
8 from bpy.utils import register_class, unregister_class
9 from bpy.types import Operator, Menu, Panel
10 from bl_operators.presets import AddPresetBase
12 from bl_ui import properties_data_camera
14 for member in dir(properties_data_camera):
15 subclass = getattr(properties_data_camera, member)
16 if hasattr(subclass, "COMPAT_ENGINES"):
17 subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
18 del properties_data_camera
20 # -------- Use only a subset of the world panels
21 # from bl_ui import properties_world
23 # # TORECREATE##DEPRECATED#properties_world.WORLD_PT_preview.COMPAT_ENGINES.add('POVRAY_RENDER')
24 # properties_world.WORLD_PT_context_world.COMPAT_ENGINES.add('POVRAY_RENDER')
25 # # TORECREATE##DEPRECATED#properties_world.WORLD_PT_world.COMPAT_ENGINES.add('POVRAY_RENDER')
26 # del properties_world
28 # -------- #
29 # Physics Main wrapping every class 'as is'
30 from bl_ui import properties_physics_common
32 for member in dir(properties_physics_common):
33 subclass = getattr(properties_physics_common, member)
34 if hasattr(subclass, "COMPAT_ENGINES"):
35 subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
36 del properties_physics_common
38 # Physics Rigid Bodies wrapping every class 'as is'
39 from bl_ui import properties_physics_rigidbody
41 for member in dir(properties_physics_rigidbody):
42 subclass = getattr(properties_physics_rigidbody, member)
43 if hasattr(subclass, "COMPAT_ENGINES"):
44 subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
45 del properties_physics_rigidbody
47 # Physics Rigid Body Constraint wrapping every class 'as is'
48 from bl_ui import properties_physics_rigidbody_constraint
50 for member in dir(properties_physics_rigidbody_constraint):
51 subclass = getattr(properties_physics_rigidbody_constraint, member)
52 if hasattr(subclass, "COMPAT_ENGINES"):
53 subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
54 del properties_physics_rigidbody_constraint
56 # Physics Smoke and fluids wrapping every class 'as is'
57 from bl_ui import properties_physics_fluid
59 for member in dir(properties_physics_fluid):
60 subclass = getattr(properties_physics_fluid, member)
61 if hasattr(subclass, "COMPAT_ENGINES"):
62 subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
63 del properties_physics_fluid
65 # Physics softbody wrapping every class 'as is'
66 from bl_ui import properties_physics_softbody
68 for member in dir(properties_physics_softbody):
69 subclass = getattr(properties_physics_softbody, member)
70 if hasattr(subclass, "COMPAT_ENGINES"):
71 subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
72 del properties_physics_softbody
74 # Physics Field wrapping every class 'as is'
75 from bl_ui import properties_physics_field
77 for member in dir(properties_physics_field):
78 subclass = getattr(properties_physics_field, member)
79 if hasattr(subclass, "COMPAT_ENGINES"):
80 subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
81 del properties_physics_field
83 # Physics Cloth wrapping every class 'as is'
84 from bl_ui import properties_physics_cloth
86 for member in dir(properties_physics_cloth):
87 subclass = getattr(properties_physics_cloth, member)
88 if hasattr(subclass, "COMPAT_ENGINES"):
89 subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
90 del properties_physics_cloth
92 # Physics Dynamic Paint wrapping every class 'as is'
93 from bl_ui import properties_physics_dynamicpaint
95 for member in dir(properties_physics_dynamicpaint):
96 subclass = getattr(properties_physics_dynamicpaint, member)
97 if hasattr(subclass, "COMPAT_ENGINES"):
98 subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
99 del properties_physics_dynamicpaint
101 from bl_ui import properties_particle
103 for member in dir(properties_particle): # add all "particle" panels from blender
104 subclass = getattr(properties_particle, member)
105 if hasattr(subclass, "COMPAT_ENGINES"):
106 subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
107 del properties_particle
110 class CameraDataButtonsPanel:
111 """Use this class to define buttons from the camera data tab of
112 properties window."""
114 bl_space_type = "PROPERTIES"
115 bl_region_type = "WINDOW"
116 bl_context = "data"
117 COMPAT_ENGINES = {"POVRAY_RENDER"}
119 @classmethod
120 def poll(cls, context):
121 cam = context.camera
122 rd = context.scene.render
123 return cam and (rd.engine in cls.COMPAT_ENGINES)
126 class WorldButtonsPanel:
127 """Use this class to define buttons from the world tab of
128 properties window."""
130 bl_space_type = "PROPERTIES"
131 bl_region_type = "WINDOW"
132 bl_context = "world"
133 COMPAT_ENGINES = {"POVRAY_RENDER"}
135 @classmethod
136 def poll(cls, context):
137 wld = context.world
138 rd = context.scene.render
139 return wld and (rd.engine in cls.COMPAT_ENGINES)
142 # ---------------------------------------------------------------- #
143 # Camera Settings
144 # ---------------------------------------------------------------- #
145 class CAMERA_PT_POV_cam_dof(CameraDataButtonsPanel, Panel):
146 """Use this class for camera depth of field focal blur buttons."""
148 bl_label = "POV Aperture"
149 COMPAT_ENGINES = {"POVRAY_RENDER"}
150 bl_parent_id = "DATA_PT_camera_dof_aperture"
151 bl_options = {"HIDE_HEADER"}
152 # def draw_header(self, context):
153 # cam = context.camera
155 # self.layout.prop(cam.pov, "dof_enable", text="")
157 def draw(self, context):
158 layout = self.layout
160 cam = context.camera
162 layout.active = cam.dof.use_dof
163 layout.use_property_split = True # Active single-column layout
165 flow = layout.grid_flow(
166 row_major=True, columns=0, even_columns=True, even_rows=False, align=False
169 col = flow.column()
170 col.label(text="F-Stop value will export as")
171 col.label(text="POV aperture : " + "%.3f" % (1 / cam.dof.aperture_fstop * 1000))
173 col = flow.column()
174 col.prop(cam.pov, "dof_samples_min")
175 col.prop(cam.pov, "dof_samples_max")
176 col.prop(cam.pov, "dof_variance")
177 col.prop(cam.pov, "dof_confidence")
180 class CAMERA_PT_POV_cam_nor(CameraDataButtonsPanel, Panel):
181 """Use this class for camera normal perturbation buttons."""
183 bl_label = "POV Perturbation"
184 COMPAT_ENGINES = {"POVRAY_RENDER"}
186 def draw_header(self, context):
187 cam = context.camera
189 self.layout.prop(cam.pov, "normal_enable", text="")
191 def draw(self, context):
192 layout = self.layout
194 cam = context.camera
196 layout.active = cam.pov.normal_enable
198 layout.prop(cam.pov, "normal_patterns")
199 layout.prop(cam.pov, "cam_normal")
200 layout.prop(cam.pov, "turbulence")
201 layout.prop(cam.pov, "scale")
204 class CAMERA_PT_POV_replacement_text(CameraDataButtonsPanel, Panel):
205 """Use this class for camera text replacement field."""
207 bl_label = "Custom POV Code"
208 COMPAT_ENGINES = {"POVRAY_RENDER"}
210 def draw(self, context):
211 layout = self.layout
213 cam = context.camera
215 col = layout.column()
216 col.label(text="Replace properties with:")
217 col.prop(cam.pov, "replacement_text", text="")
220 # ---------------------------------------------------------------- #
221 # World background and sky sphere Settings
222 # ---------------------------------------------------------------- #
225 class WORLD_PT_POV_world(WorldButtonsPanel, Panel):
226 """Use this class to define pov world buttons"""
228 bl_label = "World"
230 COMPAT_ENGINES = {"POVRAY_RENDER"}
232 def draw(self, context):
233 layout = self.layout
235 world = context.world.pov
237 row = layout.row(align=True)
238 row.menu(WORLD_MT_POV_presets.__name__, text=WORLD_MT_POV_presets.bl_label)
239 row.operator(WORLD_OT_POV_add_preset.bl_idname, text="", icon="ADD")
240 row.operator(WORLD_OT_POV_add_preset.bl_idname, text="", icon="REMOVE").remove_active = True
242 row = layout.row()
243 row.prop(world, "use_sky_paper")
244 row.prop(world, "use_sky_blend")
245 row.prop(world, "use_sky_real")
247 row = layout.row()
248 row.column().prop(world, "horizon_color")
249 col = row.column()
250 col.prop(world, "zenith_color")
251 col.active = world.use_sky_blend
252 row.column().prop(world, "ambient_color")
254 # row = layout.row()
255 # row.prop(world, "exposure") #Re-implement later as a light multiplier
256 # row.prop(world, "color_range")
259 class WORLD_PT_POV_mist(WorldButtonsPanel, Panel):
260 """Use this class to define pov mist buttons."""
262 bl_label = "Mist"
263 bl_options = {"DEFAULT_CLOSED"}
264 COMPAT_ENGINES = {"POVRAY_RENDER"}
266 def draw_header(self, context):
267 world = context.world
269 self.layout.prop(world.mist_settings, "use_mist", text="")
271 def draw(self, context):
272 layout = self.layout
274 world = context.world
276 layout.active = world.mist_settings.use_mist
278 split = layout.split()
280 col = split.column()
281 col.prop(world.mist_settings, "intensity")
282 col.prop(world.mist_settings, "start")
284 col = split.column()
285 col.prop(world.mist_settings, "depth")
286 col.prop(world.mist_settings, "height")
288 layout.prop(world.mist_settings, "falloff")
291 class WORLD_MT_POV_presets(Menu):
292 """Apply world preset to all concerned properties"""
294 bl_label = "World Presets"
295 preset_subdir = "pov/world"
296 preset_operator = "script.execute_preset"
297 draw = bpy.types.Menu.draw_preset
300 class WORLD_OT_POV_add_preset(AddPresetBase, Operator):
301 """Add a World Preset recording current values"""
303 bl_idname = "object.world_preset_add"
304 bl_label = "Add World Preset"
305 preset_menu = "WORLD_MT_POV_presets"
307 # variable used for all preset values
308 preset_defines = ["scene = bpy.context.scene"]
310 # properties to store in the preset
311 preset_values = [
312 "scene.world.use_sky_blend",
313 "scene.world.horizon_color",
314 "scene.world.zenith_color",
315 "scene.world.ambient_color",
316 "scene.world.mist_settings.use_mist",
317 "scene.world.mist_settings.intensity",
318 "scene.world.mist_settings.depth",
319 "scene.world.mist_settings.start",
320 "scene.pov.media_enable",
321 "scene.pov.media_scattering_type",
322 "scene.pov.media_samples",
323 "scene.pov.media_diffusion_scale",
324 "scene.pov.media_diffusion_color",
325 "scene.pov.media_absorption_scale",
326 "scene.pov.media_absorption_color",
327 "scene.pov.media_eccentricity",
330 # where to store the preset
331 preset_subdir = "pov/world"
334 class RENDER_PT_POV_media(WorldButtonsPanel, Panel):
335 """Use this class to define a pov global atmospheric media buttons."""
337 bl_label = "Atmosphere Media"
338 COMPAT_ENGINES = {"POVRAY_RENDER"}
340 def draw_header(self, context):
341 scene = context.scene
343 self.layout.prop(scene.pov, "media_enable", text="")
345 def draw(self, context):
346 layout = self.layout
348 scene = context.scene
350 layout.active = scene.pov.media_enable
352 col = layout.column()
353 col.prop(scene.pov, "media_scattering_type", text="")
354 col = layout.column()
355 col.prop(scene.pov, "media_samples", text="Samples")
356 split = layout.split()
357 col = split.column(align=True)
358 col.label(text="Scattering:")
359 col.prop(scene.pov, "media_diffusion_scale")
360 col.prop(scene.pov, "media_diffusion_color", text="")
361 col = split.column(align=True)
362 col.label(text="Absorption:")
363 col.prop(scene.pov, "media_absorption_scale")
364 col.prop(scene.pov, "media_absorption_color", text="")
365 if scene.pov.media_scattering_type == "5":
366 col = layout.column()
367 col.prop(scene.pov, "media_eccentricity", text="Eccentricity")
370 # ---------------------------------------------------------------- #
371 # Lights settings
372 # ---------------------------------------------------------------- #
374 # ----------------------------------------------------------------
375 # from bl_ui import properties_data_light
376 # for member in dir(properties_data_light):
377 # subclass = getattr(properties_data_light, member)
378 # try:
379 # subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
380 # except BaseException as e:
381 # print e.__doc__
382 # print('An exception occurred: {}'.format(e))
383 # pass
384 # del properties_data_light
385 # -------- LIGHTS -------- #
387 from bl_ui import properties_data_light
389 # -------- These panels are kept
390 # properties_data_light.DATA_PT_custom_props_light.COMPAT_ENGINES.add('POVRAY_RENDER')
391 # properties_data_light.DATA_PT_context_light.COMPAT_ENGINES.add('POVRAY_RENDER')
393 # make some native panels contextual to some object variable
394 # by recreating custom panels inheriting their properties
397 class PovLightButtonsPanel(properties_data_light.DataButtonsPanel):
398 """Use this class to define buttons from the light data tab of
399 properties window."""
401 COMPAT_ENGINES = {"POVRAY_RENDER"}
402 POV_OBJECT_TYPES = {"RAINBOW"}
404 @classmethod
405 def poll(cls, context):
406 obj = context.object
407 # We use our parent class poll func too, avoids to re-define too much things...
408 return (
409 super(PovLightButtonsPanel, cls).poll(context)
410 and obj
411 and obj.pov.object_as not in cls.POV_OBJECT_TYPES
415 # We cannot inherit from RNA classes (like e.g. properties_data_mesh.DATA_PT_vertex_groups).
416 # Complex py/bpy/rna interactions (with metaclass and all) simply do not allow it to work.
417 # So we simply have to explicitly copy here the interesting bits. ;)
418 from bl_ui import properties_data_light
420 # for member in dir(properties_data_light):
421 # subclass = getattr(properties_data_light, member)
422 # try:
423 # subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
424 # except BaseException as e:
425 # print(e.__doc__)
426 # print('An exception occurred: {}'.format(e))
427 # pass
429 # Now only These panels are kept
430 properties_data_light.DATA_PT_custom_props_light.COMPAT_ENGINES.add("POVRAY_RENDER")
431 properties_data_light.DATA_PT_context_light.COMPAT_ENGINES.add("POVRAY_RENDER")
434 class LIGHT_PT_POV_preview(PovLightButtonsPanel, Panel):
435 # XXX Needs update and docstring
436 bl_label = properties_data_light.DATA_PT_preview.bl_label
438 draw = properties_data_light.DATA_PT_preview.draw
441 class LIGHT_PT_POV_light(PovLightButtonsPanel, Panel):
442 """UI panel to main pov light parameters"""
444 # bl_label = properties_data_light.DATA_PT_light.bl_label
446 # draw = properties_data_light.DATA_PT_light.draw
447 # class DATA_PT_POV_light(DataButtonsPanel, Panel):
448 bl_label = "Light"
449 # COMPAT_ENGINES = {'POVRAY_RENDER'}
451 def draw(self, context):
452 layout = self.layout
454 light = context.light
456 layout.row().prop(light, "type", expand=True)
458 split = layout.split()
460 col = split.column()
461 sub = col.column()
462 sub.prop(light, "color", text="")
463 sub.prop(light, "energy")
465 if light.type in {"POINT", "SPOT"}:
466 sub.label(text="Falloff:")
467 sub.prop(light, "falloff_type", text="")
468 sub.prop(light, "distance")
470 if light.falloff_type == "LINEAR_QUADRATIC_WEIGHTED":
471 col.label(text="Attenuation Factors:")
472 sub = col.column(align=True)
473 sub.prop(light, "linear_attenuation", slider=True, text="Linear")
474 sub.prop(light, "quadratic_attenuation", slider=True, text="Quadratic")
476 elif light.falloff_type == "INVERSE_COEFFICIENTS":
477 col.label(text="Inverse Coefficients:")
478 sub = col.column(align=True)
479 sub.prop(light, "constant_coefficient", text="Constant")
480 sub.prop(light, "linear_coefficient", text="Linear")
481 sub.prop(light, "quadratic_coefficient", text="Quadratic")
483 if light.type == "AREA":
484 col.prop(light, "distance")
486 col.separator()
488 col.prop(light, "shape")
490 sub = col.column(align=True)
492 if light.shape in {'SQUARE', 'DISK'}:
493 sub.prop(light, "size")
494 elif light.shape in {'RECTANGLE', 'ELLIPSE'}:
495 sub.prop(light, "size", text="Size X")
496 sub.prop(light, "size_y", text="Y")
498 # restore later as interface to POV light groups ?
499 # col = split.column()
500 # col.prop(light, "use_own_layer", text="This Layer Only")
503 class LIGHT_MT_POV_presets(Menu):
504 """Use this class to define preset menu for pov lights."""
506 bl_label = "Lamp Presets"
507 preset_subdir = "pov/light"
508 preset_operator = "script.execute_preset"
509 draw = bpy.types.Menu.draw_preset
512 class LIGHT_OT_POV_add_preset(AddPresetBase, Operator):
513 """Operator to add a Light Preset"""
515 bl_idname = "object.light_preset_add"
516 bl_label = "Add Light Preset"
517 preset_menu = "LIGHT_MT_POV_presets"
519 # variable used for all preset values
520 preset_defines = ["lightdata = bpy.context.object.data"]
522 # properties to store in the preset
523 preset_values = ["lightdata.type", "lightdata.color"]
525 # where to store the preset
526 preset_subdir = "pov/light"
529 # Draw into the existing light panel
530 def light_panel_func(self, context):
531 """Menu to browse and add light preset"""
532 layout = self.layout
534 row = layout.row(align=True)
535 row.menu(LIGHT_MT_POV_presets.__name__, text=LIGHT_MT_POV_presets.bl_label)
536 row.operator(LIGHT_OT_POV_add_preset.bl_idname, text="", icon="ADD")
537 row.operator(LIGHT_OT_POV_add_preset.bl_idname, text="", icon="REMOVE").remove_active = True
540 """#TORECREATE##DEPRECATED#
541 class LIGHT_PT_POV_sunsky(PovLightButtonsPanel, Panel):
542 bl_label = properties_data_light.DATA_PT_sunsky.bl_label
544 @classmethod
545 def poll(cls, context):
546 lamp = context.light
547 engine = context.scene.render.engine
548 return (lamp and lamp.type == 'SUN') and (engine in cls.COMPAT_ENGINES)
550 draw = properties_data_light.DATA_PT_sunsky.draw
555 class LIGHT_PT_POV_shadow(PovLightButtonsPanel, Panel):
556 # Todo : update and docstring
557 bl_label = "Shadow"
559 @classmethod
560 def poll(cls, context):
561 light = context.light
562 engine = context.scene.render.engine
563 return light and (engine in cls.COMPAT_ENGINES)
565 def draw(self, context):
566 layout = self.layout
568 light = context.light
570 layout.row().prop(light.pov, "shadow_method", expand=True)
572 split = layout.split()
573 col = split.column()
575 col.prop(light.pov, "use_halo")
576 sub = col.column(align=True)
577 sub.active = light.pov.use_halo
578 sub.prop(light.pov, "halo_intensity", text="Intensity")
580 if light.pov.shadow_method == "NOSHADOW" and light.type == "AREA":
581 split = layout.split()
583 col = split.column()
584 col.label(text="Form factor sampling:")
586 sub = col.row(align=True)
588 if light.shape == "SQUARE":
589 sub.prop(light, "shadow_ray_samples_x", text="Samples")
590 elif light.shape == "RECTANGLE":
591 sub.prop(light.pov, "shadow_ray_samples_x", text="Samples X")
592 sub.prop(light.pov, "shadow_ray_samples_y", text="Samples Y")
594 if light.pov.shadow_method != "NOSHADOW":
595 split = layout.split()
597 col = split.column()
598 col.prop(light, "shadow_color", text="")
600 # col = split.column()
601 # col.prop(light.pov, "use_shadow_layer", text="This Layer Only")
602 # col.prop(light.pov, "use_only_shadow")
604 if light.pov.shadow_method == "RAY_SHADOW":
605 split = layout.split()
607 col = split.column()
608 col.label(text="Sampling:")
610 if light.type in {"POINT", "SUN", "SPOT"}:
611 sub = col.row()
613 sub.prop(light.pov, "shadow_ray_samples_x", text="Samples")
614 # any equivalent in pov?
615 # sub.prop(light, "shadow_soft_size", text="Soft Size")
617 elif light.type == "AREA":
618 sub = col.row(align=True)
620 if light.shape == "SQUARE":
621 sub.prop(light.pov, "shadow_ray_samples_x", text="Samples")
622 elif light.shape == "RECTANGLE":
623 sub.prop(light.pov, "shadow_ray_samples_x", text="Samples X")
624 sub.prop(light.pov, "shadow_ray_samples_y", text="Samples Y")
627 class LIGHT_PT_POV_spot(PovLightButtonsPanel, Panel):
628 bl_label = properties_data_light.DATA_PT_spot.bl_label
629 bl_parent_id = "LIGHT_PT_POV_light"
630 bl_context = "data"
632 @classmethod
633 def poll(cls, context):
634 lamp = context.light
635 engine = context.scene.render.engine
636 return (lamp and lamp.type == "SPOT") and (engine in cls.COMPAT_ENGINES)
638 draw = properties_data_light.DATA_PT_spot.draw
641 class LIGHT_PT_POV_falloff_curve(PovLightButtonsPanel, Panel):
642 bl_label = properties_data_light.DATA_PT_falloff_curve.bl_label
643 bl_options = properties_data_light.DATA_PT_falloff_curve.bl_options
645 @classmethod
646 def poll(cls, context):
647 lamp = context.light
648 engine = context.scene.render.engine
650 return (
651 lamp and lamp.type in {"POINT", "SPOT"} and lamp.falloff_type == "CUSTOM_CURVE"
652 ) and (engine in cls.COMPAT_ENGINES)
654 draw = properties_data_light.DATA_PT_falloff_curve.draw
657 class OBJECT_PT_POV_rainbow(PovLightButtonsPanel, Panel):
658 """Use this class to define buttons from the rainbow panel of
659 properties window. inheriting lamp buttons panel class"""
661 bl_label = "POV-Ray Rainbow"
662 COMPAT_ENGINES = {"POVRAY_RENDER"}
663 # bl_options = {'HIDE_HEADER'}
665 @classmethod
666 def poll(cls, context):
667 engine = context.scene.render.engine
668 obj = context.object
669 return obj and obj.pov.object_as == "RAINBOW" and (engine in cls.COMPAT_ENGINES)
671 def draw(self, context):
672 layout = self.layout
674 obj = context.object
676 col = layout.column()
678 if obj.pov.object_as == "RAINBOW":
679 if not obj.pov.unlock_parameters:
680 col.prop(
681 obj.pov, "unlock_parameters", text="Exported parameters below", icon="LOCKED"
683 col.label(text="Rainbow projection angle: " + str(obj.data.spot_size))
684 col.label(text="Rainbow width: " + str(obj.data.spot_blend))
685 col.label(text="Rainbow distance: " + str(obj.data.shadow_buffer_clip_start))
686 col.label(text="Rainbow arc angle: " + str(obj.pov.arc_angle))
687 col.label(text="Rainbow falloff angle: " + str(obj.pov.falloff_angle))
689 else:
690 col.prop(
691 obj.pov, "unlock_parameters", text="Edit exported parameters", icon="UNLOCKED"
693 col.label(text="3D view proxy may get out of synch")
694 col.active = obj.pov.unlock_parameters
696 layout.operator("pov.cone_update", text="Update", icon="MESH_CONE")
698 # col.label(text="Parameters:")
699 col.prop(obj.data, "spot_size", text="Rainbow Projection Angle")
700 col.prop(obj.data, "spot_blend", text="Rainbow width")
701 col.prop(obj.data, "shadow_buffer_clip_start", text="Visibility distance")
702 col.prop(obj.pov, "arc_angle")
703 col.prop(obj.pov, "falloff_angle")
706 del properties_data_light
709 classes = (
710 WORLD_PT_POV_world,
711 WORLD_MT_POV_presets,
712 WORLD_OT_POV_add_preset,
713 WORLD_PT_POV_mist,
714 RENDER_PT_POV_media,
715 LIGHT_PT_POV_preview,
716 LIGHT_PT_POV_light,
717 LIGHT_PT_POV_shadow,
718 LIGHT_PT_POV_spot,
719 LIGHT_MT_POV_presets,
720 LIGHT_OT_POV_add_preset,
721 OBJECT_PT_POV_rainbow,
722 CAMERA_PT_POV_cam_dof,
723 CAMERA_PT_POV_cam_nor,
724 CAMERA_PT_POV_replacement_text,
728 def register():
730 for cls in classes:
731 register_class(cls)
732 LIGHT_PT_POV_light.prepend(light_panel_func)
735 def unregister():
736 LIGHT_PT_POV_light.remove(light_panel_func)
737 for cls in reversed(classes):
738 unregister_class(cls)