blender-addons/sun_position/properties.py
2023-07-05 09:41:03 +02:00

320 lines
9.6 KiB
Python

# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
from bpy.types import AddonPreferences, PropertyGroup
from bpy.props import (StringProperty, EnumProperty, IntProperty,
FloatProperty, BoolProperty, PointerProperty)
from bpy.app.translations import pgettext_iface as iface_
from .draw import north_update, surface_update, analemmas_update
from .geo import parse_position
from .sun_calc import format_lat_long, sun, update_time, move_sun
from math import pi
from datetime import datetime
TODAY = datetime.today()
############################################################################
# Sun panel properties
############################################################################
parse_success = True
def lat_long_update(self, context):
global parse_success
parse_success = True
sun_update(self, context)
def get_coordinates(self):
if parse_success:
return format_lat_long(self.latitude, self.longitude)
return iface_("ERROR: Could not parse coordinates")
def set_coordinates(self, value):
parsed_co = parse_position(value)
global parse_success
if parsed_co is not None and len(parsed_co) == 2:
latitude, longitude = parsed_co
self.latitude, self.longitude = latitude, longitude
else:
parse_success = False
sun_update(self, bpy.context)
def sun_update(self, context):
sun_props = context.scene.sun_pos_properties
update_time(context)
move_sun(context)
if sun_props.show_surface:
surface_update(self, context)
if sun_props.show_analemmas:
analemmas_update(self, context)
if sun_props.show_north:
north_update(self, context)
class SunPosProperties(PropertyGroup):
usage_mode: EnumProperty(
name="Usage Mode",
description="Operate in normal mode or environment texture mode",
items=(
('NORMAL', "Normal", ""),
('HDR', "Sun + HDR texture", ""),
),
default='NORMAL',
update=sun_update)
use_daylight_savings: BoolProperty(
name="Daylight Savings",
description="Daylight savings time adds 1 hour to standard time",
default=False,
update=sun_update)
use_refraction: BoolProperty(
name="Use Refraction",
description="Show the apparent Sun position due to atmospheric refraction",
default=True,
update=sun_update)
show_north: BoolProperty(
name="Show North",
description="Draw a line pointing to the north",
default=False,
update=north_update)
north_offset: FloatProperty(
name="North Offset",
description="Rotate the scene to choose the North direction",
unit="ROTATION",
soft_min=-pi, soft_max=pi, step=10.0, default=0.0,
update=sun_update)
show_surface: BoolProperty(
name="Show Surface",
description="Draw the surface that the Sun occupies in the sky",
default=False,
update=surface_update)
show_analemmas: BoolProperty(
name="Show Analemmas",
description="Draw Sun analemmas. These help visualize the motion of the Sun in the sky during the year, for each hour of the day",
default=False,
update=analemmas_update)
coordinates: StringProperty(
name="Coordinates",
description="Enter coordinates from an online map",
get=get_coordinates,
set=set_coordinates,
options={'SKIP_SAVE'})
latitude: FloatProperty(
name="Latitude",
description="Latitude: (+) Northern (-) Southern",
soft_min=-90.0, soft_max=90.0,
step=5, precision=3,
default=0.0,
update=lat_long_update)
longitude: FloatProperty(
name="Longitude",
description="Longitude: (-) West of Greenwich (+) East of Greenwich",
soft_min=-180.0, soft_max=180.0,
step=5, precision=3,
default=0.0,
update=lat_long_update)
sunrise_time: FloatProperty(
name="Sunrise Time",
description="Time at which the Sun rises",
soft_min=0.0, soft_max=24.0,
default=0.0,
get=lambda _: sun.sunrise)
sunset_time: FloatProperty(
name="Sunset Time",
description="Time at which the Sun sets",
soft_min=0.0, soft_max=24.0,
default=0.0,
get=lambda _: sun.sunset)
sun_elevation: FloatProperty(
name="Sun Elevation",
description="Elevation angle of the Sun",
soft_min=-pi/2, soft_max=pi/2,
precision=3,
default=0.0,
unit="ROTATION",
get=lambda _: sun.elevation)
sun_azimuth: FloatProperty(
name="Sun Azimuth",
description="Rotation angle of the Sun from the direction of the north",
soft_min=-pi, soft_max=pi,
precision=3,
default=0.0,
unit="ROTATION",
get=lambda _: sun.azimuth - bpy.context.scene.sun_pos_properties.north_offset)
month: IntProperty(
name="Month",
min=1, max=12, default=TODAY.month,
update=sun_update)
day: IntProperty(
name="Day",
min=1, max=31, default=TODAY.day,
update=sun_update)
year: IntProperty(
name="Year",
min=1, max=4000, default=TODAY.year,
update=sun_update)
use_day_of_year: BoolProperty(
description="Use a single value for the day of year",
name="Use day of year",
default=False,
update=sun_update)
day_of_year: IntProperty(
name="Day of Year",
min=1, max=366, default=1,
update=sun_update)
UTC_zone: FloatProperty(
name="UTC Zone",
description="Difference from Greenwich, England, in hours",
precision=1,
min=-14.0, max=13, step=50, default=0.0,
update=sun_update)
time: FloatProperty(
name="Time",
description="Time of the day",
precision=4,
soft_min=0.0, soft_max=23.9999, step=1.0, default=12.0,
update=sun_update)
sun_distance: FloatProperty(
name="Distance",
description="Distance to the Sun from the origin",
unit="LENGTH",
min=0.0, soft_max=3000.0, step=10.0, default=50.0,
update=sun_update)
sun_object: PointerProperty(
name="Sun Object",
type=bpy.types.Object,
description="Sun object to use in the scene",
poll=lambda self, obj: obj.type == 'LIGHT',
update=sun_update)
object_collection: PointerProperty(
name="Collection",
type=bpy.types.Collection,
description="Collection of objects used to visualize the motion of the Sun",
update=sun_update)
object_collection_type: EnumProperty(
name="Display type",
description="Type of Sun motion to visualize.",
items=(
('ANALEMMA', "Analemma", "Trajectory of the Sun in the sky during the year, for a given time of the day"),
('DIURNAL', "Diurnal", "Trajectory of the Sun in the sky during a single day"),
),
default='ANALEMMA',
update=sun_update)
sky_texture: StringProperty(
name="Sky Texture",
default="",
description="Name of the sky texture to use",
update=sun_update)
hdr_texture: StringProperty(
default="Environment Texture",
name="Environment Texture",
description="Name of the environment texture to use. World nodes must be enabled "
"and the color set to an environment Texture",
update=sun_update)
hdr_azimuth: FloatProperty(
name="Rotation",
description="Rotation angle of the Sun and environment texture",
unit="ROTATION",
step=10.0,
default=0.0, precision=3,
update=sun_update)
hdr_elevation: FloatProperty(
name="Elevation",
description="Elevation angle of the Sun",
unit="ROTATION",
step=10.0,
default=0.0, precision=3,
update=sun_update)
bind_to_sun: BoolProperty(
name="Bind Texture to Sun",
description="If enabled, the environment texture moves with the Sun",
default=False,
update=sun_update)
time_spread: FloatProperty(
name="Time Spread",
description="Time period around which to spread object collection",
precision=4,
soft_min=1.0, soft_max=24.0, step=1.0, default=23.0,
update=sun_update)
############################################################################
# Preference panel properties
############################################################################
class SunPosAddonPreferences(AddonPreferences):
bl_idname = __package__
show_overlays: BoolProperty(
name="Show Overlays",
description="Display overlays in the viewport: the direction of the north, analemmas and the Sun surface",
default=True,
update=sun_update)
show_refraction: BoolProperty(
name="Refraction",
description="Show Sun Refraction choice",
default=True)
show_az_el: BoolProperty(
name="Azimuth and Elevation Info",
description="Show azimuth and solar elevation info",
default=True)
show_rise_set: BoolProperty(
name="Sunrise and Sunset Info",
description="Show sunrise and sunset labels",
default=True)
def draw(self, context):
layout = self.layout
box = layout.box()
col = box.column()
col.label(text="Show options and info:")
flow = col.grid_flow(columns=0, even_columns=True, even_rows=False, align=False)
flow.prop(self, "show_refraction")
flow.prop(self, "show_overlays")
flow.prop(self, "show_az_el")
flow.prop(self, "show_rise_set")