1 # SPDX-FileCopyrightText: 2019-2023 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
6 from bpy
.types
import AddonPreferences
, PropertyGroup
7 from bpy
.props
import (StringProperty
, EnumProperty
, IntProperty
,
8 FloatProperty
, BoolProperty
, PointerProperty
)
9 from bpy
.app
.translations
import pgettext_iface
as iface_
12 from .draw
import north_update
, surface_update
, analemmas_update
13 from .geo
import parse_position
14 from .sun_calc
import format_lat_long
, sun
, update_time
, move_sun
17 from datetime
import datetime
, date
18 TODAY
= datetime
.today()
20 ############################################################################
21 # Sun panel properties
22 ############################################################################
27 def lat_long_update(self
, context
):
30 sun_update(self
, context
)
33 def get_coordinates(self
):
35 return format_lat_long(self
.latitude
, self
.longitude
)
36 return iface_("ERROR: Could not parse coordinates")
40 """Getter for the day property.
42 Not all days are valid, depending on month.
43 Invalid days are only at the end of the month so they
44 can be checked by just decreasing the value until it is valid.
46 day
= self
.get("day", 1)
50 date(self
.year
, self
.month
, day
)
57 def set_day(self
, value
):
61 def set_coordinates(self
, value
):
62 parsed_co
= parse_position(value
)
65 if parsed_co
is not None and len(parsed_co
) == 2:
66 latitude
, longitude
= parsed_co
67 self
.latitude
, self
.longitude
= latitude
, longitude
71 sun_update(self
, bpy
.context
)
74 def sun_update(self
, context
):
75 sun_props
= context
.scene
.sun_pos_properties
80 if sun_props
.show_surface
:
81 surface_update(self
, context
)
82 if sun_props
.show_analemmas
:
83 analemmas_update(self
, context
)
84 if sun_props
.show_north
:
85 north_update(self
, context
)
88 class SunPosProperties(PropertyGroup
):
89 usage_mode
: EnumProperty(
91 description
="Operate in normal mode or environment texture mode",
93 ('NORMAL', "Normal", ""),
94 ('HDR', "Sun + HDR texture", ""),
99 use_daylight_savings
: BoolProperty(
100 name
="Daylight Savings",
101 description
="Daylight savings time adds 1 hour to standard time",
105 use_refraction
: BoolProperty(
106 name
="Use Refraction",
107 description
="Show the apparent Sun position due to atmospheric refraction",
111 show_north
: BoolProperty(
113 description
="Draw a line pointing to the north",
117 north_offset
: FloatProperty(
119 description
="Rotate the scene to choose the North direction",
121 soft_min
=-pi
, soft_max
=pi
, step
=10.0, default
=0.0,
124 show_surface
: BoolProperty(
126 description
="Draw the surface that the Sun occupies in the sky",
128 update
=surface_update
)
130 show_analemmas
: BoolProperty(
131 name
="Show Analemmas",
132 description
="Draw Sun analemmas. These help visualize the motion of the Sun in the sky during the year, for each hour of the day",
134 update
=analemmas_update
)
136 coordinates
: StringProperty(
138 description
="Enter coordinates from an online map",
141 default
="00°00′00.00″ 00°00′00.00″",
142 options
={'SKIP_SAVE'})
144 latitude
: FloatProperty(
146 description
="Latitude: (+) Northern (-) Southern",
147 soft_min
=-90.0, soft_max
=90.0,
150 update
=lat_long_update
)
152 longitude
: FloatProperty(
154 description
="Longitude: (-) West of Greenwich (+) East of Greenwich",
155 soft_min
=-180.0, soft_max
=180.0,
158 update
=lat_long_update
)
160 sunrise_time
: FloatProperty(
162 description
="Time at which the Sun rises",
163 soft_min
=0.0, soft_max
=24.0,
165 get
=lambda _
: sun
.sunrise
)
167 sunset_time
: FloatProperty(
169 description
="Time at which the Sun sets",
170 soft_min
=0.0, soft_max
=24.0,
172 get
=lambda _
: sun
.sunset
)
174 sun_elevation
: FloatProperty(
175 name
="Sun Elevation",
176 description
="Elevation angle of the Sun",
177 soft_min
=-pi
/2, soft_max
=pi
/2,
181 get
=lambda _
: sun
.elevation
)
183 sun_azimuth
: FloatProperty(
185 description
="Rotation angle of the Sun from the direction of the north",
186 soft_min
=-pi
, soft_max
=pi
,
190 get
=lambda _
: sun
.azimuth
- bpy
.context
.scene
.sun_pos_properties
.north_offset
)
194 min=1, max=12, default
=TODAY
.month
,
199 min=1, max=31, default
=TODAY
.day
,
206 min=1, max=4000, default
=TODAY
.year
,
209 use_day_of_year
: BoolProperty(
210 description
="Use a single value for the day of year",
211 name
="Use day of year",
215 day_of_year
: IntProperty(
217 min=1, max=366, default
=1,
220 UTC_zone
: FloatProperty(
222 description
="Difference from Greenwich, England, in hours",
224 min=-14.0, max=13, step
=50, default
=0.0,
229 description
="Time of the day",
231 soft_min
=0.0, soft_max
=23.9999, step
=1.0, default
=12.0,
234 sun_distance
: FloatProperty(
236 description
="Distance to the Sun from the origin",
238 min=0.0, soft_max
=3000.0, step
=10.0, default
=50.0,
241 sun_object
: PointerProperty(
243 type=bpy
.types
.Object
,
244 description
="Sun object to use in the scene",
245 poll
=lambda self
, obj
: obj
.type == 'LIGHT',
248 object_collection
: PointerProperty(
250 type=bpy
.types
.Collection
,
251 description
="Collection of objects used to visualize the motion of the Sun",
254 object_collection_type
: EnumProperty(
256 description
="Type of Sun motion to visualize",
258 ('ANALEMMA', "Analemma", "Trajectory of the Sun in the sky during the year, for a given time of the day"),
259 ('DIURNAL', "Diurnal", "Trajectory of the Sun in the sky during a single day"),
264 sky_texture
: StringProperty(
267 description
="Name of the sky texture to use",
270 hdr_texture
: StringProperty(
271 default
="Environment Texture",
272 name
="Environment Texture",
273 description
="Name of the environment texture to use. World nodes must be enabled "
274 "and the color set to an environment Texture",
277 hdr_azimuth
: FloatProperty(
279 description
="Rotation angle of the Sun and environment texture",
282 default
=0.0, precision
=3,
285 hdr_elevation
: FloatProperty(
287 description
="Elevation angle of the Sun",
290 default
=0.0, precision
=3,
293 bind_to_sun
: BoolProperty(
294 name
="Bind Texture to Sun",
295 description
="If enabled, the environment texture moves with the Sun",
299 time_spread
: FloatProperty(
301 description
="Time period around which to spread object collection",
303 soft_min
=1.0, soft_max
=24.0, step
=1.0, default
=23.0,
306 ############################################################################
307 # Preference panel properties
308 ############################################################################
311 class SunPosAddonPreferences(AddonPreferences
):
312 bl_idname
= __package__
314 show_overlays
: BoolProperty(
315 name
="Show Overlays",
316 description
="Display overlays in the viewport: the direction of the north, analemmas and the Sun surface",
320 show_refraction
: BoolProperty(
322 description
="Show Sun Refraction choice",
325 show_az_el
: BoolProperty(
326 name
="Azimuth and Elevation Info",
327 description
="Show azimuth and solar elevation info",
330 show_rise_set
: BoolProperty(
331 name
="Sunrise and Sunset Info",
332 description
="Show sunrise and sunset labels",
335 def draw(self
, context
):
341 col
.label(text
="Show options and info:")
342 flow
= col
.grid_flow(columns
=0, even_columns
=True, even_rows
=False, align
=False)
343 flow
.prop(self
, "show_refraction")
344 flow
.prop(self
, "show_overlays")
345 flow
.prop(self
, "show_az_el")
346 flow
.prop(self
, "show_rise_set")