1 # SPDX-License-Identifier: GPL-2.0-or-later
4 from bpy
.types
import Operator
, Menu
5 from bl_operators
.presets
import AddPresetBase
8 from .sun_calc
import (format_lat_long
, format_time
, format_hms
, sun
)
11 # -------------------------------------------------------------------
12 # Choice list of places, month and day at 12:00 noon
13 # -------------------------------------------------------------------
16 class SUNPOS_MT_Presets(Menu
):
17 bl_label
= "Sun Position Presets"
18 preset_subdir
= "operator/sun_position"
19 preset_operator
= "script.execute_preset"
20 draw
= Menu
.draw_preset
23 class SUNPOS_OT_AddPreset(AddPresetBase
, Operator
):
24 '''Add Sun Position preset'''
25 bl_idname
= "world.sunpos_add_preset"
26 bl_label
= "Add Sun Position preset"
27 preset_menu
= "SUNPOS_MT_Presets"
29 # variable used for all preset values
31 "sun_props = bpy.context.scene.sun_pos_properties"
34 # properties to store in the preset
41 "sun_props.use_daylight_savings",
43 "sun_props.longitude",
46 # where to store the preset
47 preset_subdir
= "operator/sun_position"
50 # -------------------------------------------------------------------
52 # Draw the Sun Panel, sliders, et. al.
54 # -------------------------------------------------------------------
56 class SUNPOS_PT_Panel(bpy
.types
.Panel
):
57 bl_space_type
= "PROPERTIES"
58 bl_region_type
= "WINDOW"
60 bl_label
= "Sun Position"
61 bl_options
= {'DEFAULT_CLOSED'}
63 def draw(self
, context
):
64 sp
= context
.scene
.sun_pos_properties
65 p
= context
.preferences
.addons
[__package__
].preferences
67 self
.draw_panel(context
, sp
, p
, layout
)
69 def draw_panel(self
, context
, sp
, p
, layout
):
70 col
= self
.layout
.column(align
=True)
71 col
.label(text
="Usage Mode")
73 row
.prop(sp
, "usage_mode", expand
=True)
75 if sp
.usage_mode
== "HDR":
76 self
.draw_environ_mode_panel(context
, sp
, p
, layout
)
78 self
.draw_normal_mode_panel(context
, sp
, p
, layout
)
80 def draw_environ_mode_panel(self
, context
, sp
, p
, layout
):
81 flow
= layout
.grid_flow(row_major
=True, columns
=0, even_columns
=True,
82 even_rows
=False, align
=False)
84 col
= flow
.column(align
=True)
85 col
.label(text
="Environment Texture")
87 if context
.scene
.world
is not None:
88 if context
.scene
.world
.node_tree
is not None:
89 col
.prop_search(sp
, "hdr_texture",
90 context
.scene
.world
.node_tree
, "nodes", text
="")
92 col
.label(text
="Please activate Use Nodes in the World panel.",
95 col
.label(text
="Please select World in the World panel.",
100 col
= flow
.column(align
=True)
101 col
.label(text
="Sun Object")
102 col
.prop_search(sp
, "sun_object",
103 context
.view_layer
, "objects", text
="")
106 col
= flow
.column(align
=True)
107 col
.prop(sp
, "sun_distance")
108 if not sp
.bind_to_sun
:
109 col
.prop(sp
, "hdr_elevation")
110 col
.prop(sp
, "hdr_azimuth")
113 col
= flow
.column(align
=True)
115 col
.prop(sp
, "bind_to_sun", toggle
=True, icon
="CONSTRAINT",
116 text
="Release binding")
118 col
.prop(sp
, "bind_to_sun", toggle
=True, icon
="CONSTRAINT",
119 text
="Bind Texture to Sun")
121 row
= col
.row(align
=True)
122 row
.enabled
= not sp
.bind_to_sun
123 row
.operator("world.sunpos_show_hdr", icon
='LIGHT_SUN')
125 def draw_normal_mode_panel(self
, context
, sp
, p
, layout
):
126 if p
.show_time_place
:
127 row
= layout
.row(align
=True)
128 row
.menu(SUNPOS_MT_Presets
.__name
__, text
=SUNPOS_MT_Presets
.bl_label
)
129 row
.operator(SUNPOS_OT_AddPreset
.bl_idname
, text
="", icon
='ADD')
130 row
.operator(SUNPOS_OT_AddPreset
.bl_idname
, text
="", icon
='REMOVE').remove_active
= True
132 col
= layout
.column(align
=True)
133 col
.use_property_split
= True
134 col
.use_property_decorate
= False
135 col
.prop(sp
, "sun_object")
138 col
.prop(sp
, "object_collection")
139 if sp
.object_collection
:
140 col
.prop(sp
, "object_collection_type")
141 if sp
.object_collection_type
== 'DIURNAL':
142 col
.prop(sp
, "time_spread")
145 if context
.scene
.world
is not None:
146 if context
.scene
.world
.node_tree
is not None:
147 col
.prop_search(sp
, "sky_texture",
148 context
.scene
.world
.node_tree
, "nodes")
150 col
.label(text
="Please activate Use Nodes in the World panel.",
153 col
.label(text
="Please select World in the World panel.",
156 class SUNPOS_PT_Location(bpy
.types
.Panel
):
157 bl_space_type
= "PROPERTIES"
158 bl_region_type
= "WINDOW"
160 bl_label
= "Location"
161 bl_parent_id
= "SUNPOS_PT_Panel"
164 def poll(self
, context
):
165 sp
= context
.scene
.sun_pos_properties
166 return sp
.usage_mode
!= "HDR"
168 def draw(self
, context
):
170 sp
= context
.scene
.sun_pos_properties
171 p
= context
.preferences
.addons
[__package__
].preferences
173 col
= layout
.column(align
=True)
174 col
.label(text
="Enter Coordinates")
175 col
.prop(sp
, "co_parser", text
='', icon
='URL')
179 flow
= layout
.grid_flow(row_major
=True, columns
=0, even_columns
=True, even_rows
=False, align
=False)
181 col
= flow
.column(align
=True)
182 col
.prop(sp
, "latitude")
185 row
.alignment
= 'RIGHT'
186 row
.label(text
=format_lat_long(sp
.latitude
, True))
188 col
= flow
.column(align
=True)
189 col
.prop(sp
, "longitude")
192 row
.alignment
= 'RIGHT'
193 row
.label(text
=format_lat_long(sp
.longitude
, False))
197 col
= flow
.column(align
=True)
198 col
.prop(sp
, "show_north", toggle
=True)
199 col
.prop(sp
, "north_offset")
202 if p
.show_surface
or p
.show_analemmas
:
203 col
= flow
.column(align
=True)
205 col
.prop(sp
, "show_surface", toggle
=True)
207 col
.prop(sp
, "show_analemmas", toggle
=True)
211 col
= flow
.column(align
=True)
212 split
= col
.split(factor
=0.4, align
=True)
213 split
.label(text
="Azimuth:")
214 split
.label(text
=str(round(sun
.azimuth
, 3)) + "°")
215 split
= col
.split(factor
=0.4, align
=True)
216 split
.label(text
="Elevation:")
217 split
.label(text
=str(round(sun
.elevation
, 3)) + "°")
220 if p
.show_refraction
:
222 col
.prop(sp
, "use_refraction")
226 col
.prop(sp
, "sun_distance")
230 class SUNPOS_PT_Time(bpy
.types
.Panel
):
231 bl_space_type
= "PROPERTIES"
232 bl_region_type
= "WINDOW"
235 bl_parent_id
= "SUNPOS_PT_Panel"
238 def poll(self
, context
):
239 sp
= context
.scene
.sun_pos_properties
240 return sp
.usage_mode
!= "HDR"
242 def draw(self
, context
):
244 sp
= context
.scene
.sun_pos_properties
245 p
= context
.preferences
.addons
[__package__
].preferences
247 flow
= layout
.grid_flow(row_major
=True, columns
=0, even_columns
=True, even_rows
=False, align
=False)
249 col
= flow
.column(align
=True)
250 col
.prop(sp
, "use_day_of_year",
252 if sp
.use_day_of_year
:
253 col
.prop(sp
, "day_of_year")
256 col
.prop(sp
, "month")
260 col
= flow
.column(align
=True)
262 col
.prop(sp
, "UTC_zone")
263 if p
.show_daylight_savings
:
264 col
.prop(sp
, "use_daylight_savings")
267 col
= flow
.column(align
=True)
268 lt
= format_time(sp
.time
,
269 p
.show_daylight_savings
and sp
.use_daylight_savings
,
271 ut
= format_time(sp
.time
,
272 p
.show_daylight_savings
and sp
.use_daylight_savings
,
275 col
.alignment
= 'CENTER'
277 split
= col
.split(factor
=0.5, align
=True)
278 split
.label(text
="Local:", icon
='TIME')
280 split
= col
.split(factor
=0.5, align
=True)
281 split
.label(text
="UTC:", icon
='PREVIEW_RANGE')
286 col
= flow
.column(align
=True)
287 col
.alignment
= 'CENTER'
289 sr
= format_hms(sun
.sunrise
.time
)
290 ss
= format_hms(sun
.sunset
.time
)
292 split
= col
.split(factor
=0.5, align
=True)
293 split
.label(text
="Sunrise:", icon
='LIGHT_SUN')
295 split
= col
.split(factor
=0.5, align
=True)
296 split
.label(text
="Sunset:", icon
='SOLO_ON')