Skip to content
Snippets Groups Projects
Commit 29a67357 authored by Eduardo Schilling's avatar Eduardo Schilling Committed by Damien Picard
Browse files

Sun Position: add Show Surface and Show Analemmas options

Sometimes during the design it's difficult to rapidly visualize the
Sun trajectory for a given location in the viewport.

This patch adds the possibility to visualize the sun path surface and
analemmas for each hour in the viewport.

Currently there is an option to create a collection with objects to
draw analemmas and diurnal ready for render but these new options
options give fast viewport feedback, something like the Show North
option.

Reviewed By: pioverfour

Differential Revision: https://developer.blender.org/D16936
parent 7a41cf88
No related branches found
No related tags found
No related merge requests found
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
bl_info = { bl_info = {
"name": "Sun Position", "name": "Sun Position",
"author": "Michael Martin", "author": "Michael Martin",
"version": (3, 1, 3), "version": (3, 2, 0),
"blender": (3, 0, 0), "blender": (3, 0, 0),
"location": "World > Sun Position", "location": "World > Sun Position",
"description": "Show sun position with objects and/or sky texture", "description": "Show sun position with objects and/or sky texture",
...@@ -48,6 +48,8 @@ register_classes, unregister_classes = bpy.utils.register_classes_factory( ...@@ -48,6 +48,8 @@ register_classes, unregister_classes = bpy.utils.register_classes_factory(
@persistent @persistent
def sun_scene_handler(scene): def sun_scene_handler(scene):
sun_props = bpy.context.scene.sun_pos_properties sun_props = bpy.context.scene.sun_pos_properties
sun_props.show_surface = sun_props.show_surface
sun_props.show_analemmas = sun_props.show_analemmas
sun_props.show_north = sun_props.show_north sun_props.show_north = sun_props.show_north
......
...@@ -5,7 +5,7 @@ from bpy.types import AddonPreferences, PropertyGroup ...@@ -5,7 +5,7 @@ from bpy.types import AddonPreferences, PropertyGroup
from bpy.props import (StringProperty, EnumProperty, IntProperty, from bpy.props import (StringProperty, EnumProperty, IntProperty,
FloatProperty, BoolProperty, PointerProperty) FloatProperty, BoolProperty, PointerProperty)
from .sun_calc import sun_update, parse_coordinates from .sun_calc import sun_update, parse_coordinates, surface_update, analemmas_update
from .draw import north_update from .draw import north_update
from math import pi from math import pi
...@@ -53,6 +53,18 @@ class SunPosProperties(PropertyGroup): ...@@ -53,6 +53,18 @@ class SunPosProperties(PropertyGroup):
soft_min=-pi, soft_max=pi, step=10.0, default=0.0, soft_min=-pi, soft_max=pi, step=10.0, default=0.0,
update=sun_update) update=sun_update)
show_surface: BoolProperty(
name="Show Surface",
description="Draw sun surface",
default=False,
update=surface_update)
show_analemmas: BoolProperty(
name="Show Analemmas",
description="Draw sun analemmas",
default=False,
update=analemmas_update)
latitude: FloatProperty( latitude: FloatProperty(
name="Latitude", name="Latitude",
description="Latitude: (+) Northern (-) Southern", description="Latitude: (+) Northern (-) Southern",
...@@ -186,7 +198,6 @@ class SunPosProperties(PropertyGroup): ...@@ -186,7 +198,6 @@ class SunPosProperties(PropertyGroup):
soft_min=1.0, soft_max=24.0, step=1.0, default=23.0, soft_min=1.0, soft_max=24.0, step=1.0, default=23.0,
update=sun_update) update=sun_update)
############################################################################ ############################################################################
# Preference panel properties # Preference panel properties
############################################################################ ############################################################################
...@@ -211,6 +222,18 @@ class SunPosAddonPreferences(AddonPreferences): ...@@ -211,6 +222,18 @@ class SunPosAddonPreferences(AddonPreferences):
default=True, default=True,
update=sun_update) update=sun_update)
show_surface: BoolProperty(
name="Show Surface",
description="Show sun surface choice and slider",
default=True,
update=sun_update)
show_analemmas: BoolProperty(
name="Show Analemmas",
description="Show analemmas choice and slider",
default=True,
update=sun_update)
show_refraction: BoolProperty( show_refraction: BoolProperty(
name="Refraction", name="Refraction",
description="Show sun refraction choice", description="Show sun refraction choice",
...@@ -244,6 +267,8 @@ class SunPosAddonPreferences(AddonPreferences): ...@@ -244,6 +267,8 @@ class SunPosAddonPreferences(AddonPreferences):
flow.prop(self, "show_time_place") flow.prop(self, "show_time_place")
flow.prop(self, "show_dms") flow.prop(self, "show_dms")
flow.prop(self, "show_north") flow.prop(self, "show_north")
flow.prop(self, "show_surface")
flow.prop(self, "show_analemmas")
flow.prop(self, "show_refraction") flow.prop(self, "show_refraction")
flow.prop(self, "show_az_el") flow.prop(self, "show_az_el")
flow.prop(self, "show_daylight_savings") flow.prop(self, "show_daylight_savings")
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
import bpy import bpy
from bpy.app.handlers import persistent from bpy.app.handlers import persistent
import gpu
from gpu_extras.batch import batch_for_shader
from mathutils import Euler, Vector from mathutils import Euler, Vector
import math import math
from math import degrees, radians, pi from math import degrees, radians, pi
...@@ -51,6 +53,10 @@ sun = SunInfo() ...@@ -51,6 +53,10 @@ sun = SunInfo()
def sun_update(self, context): def sun_update(self, context):
update_time(context) update_time(context)
move_sun(context) move_sun(context)
if self.show_surface:
surface_update(self, context)
if self.show_analemmas:
analemmas_update(self, context)
def parse_coordinates(self, context): def parse_coordinates(self, context):
...@@ -563,3 +569,107 @@ def mean_anomaly_sun(t): ...@@ -563,3 +569,107 @@ def mean_anomaly_sun(t):
def eccentricity_earth_orbit(t): def eccentricity_earth_orbit(t):
return (0.016708634 - 0.000042037 * t - 0.0000001267 * t ** 2) return (0.016708634 - 0.000042037 * t - 0.0000001267 * t ** 2)
def calc_surface(context):
coords = []
sun_props = context.scene.sun_pos_properties
zone = -sun_props.UTC_zone
north_offset = degrees(sun_props.north_offset)
def get_surface_coordinates(time, month):
_, theta, phi, _, _ = get_sun_coordinates(
time, sun_props.latitude, sun_props.longitude, north_offset,
zone, month, 1, sun_props.year, sun_props.sun_distance)
sun_vector = get_sun_vector(theta, phi) * sun_props.sun_distance
sun_vector.z = max(0, sun_vector.z)
return sun_vector
for month in range(1, 7):
for time in range(24):
coords.append(get_surface_coordinates(time, month))
coords.append(get_surface_coordinates(time + 1, month))
coords.append(get_surface_coordinates(time, month + 1))
coords.append(get_surface_coordinates(time, month + 1))
coords.append(get_surface_coordinates(time + 1, month + 1))
coords.append(get_surface_coordinates(time + 1, month))
return coords
def calc_analemma(context, h):
vertices = []
sun_props = context.scene.sun_pos_properties
zone = -sun_props.UTC_zone
north_offset = degrees(sun_props.north_offset)
for day_of_year in range(1, 367, 5):
day, month = day_of_year_to_month_day(sun_props.year, day_of_year)
_, theta, phi, _, _ = get_sun_coordinates(
h, sun_props.latitude, sun_props.longitude,
north_offset, zone, month, day, sun_props.year,
sun_props.sun_distance)
sun_vector = get_sun_vector(theta, phi) * sun_props.sun_distance
if sun_vector.z > 0:
vertices.append(sun_vector)
return vertices
def draw_surface(batch, shader):
blend = gpu.state.blend_get()
gpu.state.blend_set("ALPHA")
shader.uniform_float("color", (.8, .6, 0, 0.2))
batch.draw(shader)
gpu.state.blend_set(blend)
def draw_analemmas(batch, shader):
shader.uniform_float("color", (1, 0, 0, 1))
batch.draw(shader)
_handle_surface = None
def surface_update(self, context):
global _handle_surface
if self.show_surface:
coords = calc_surface(context)
shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
batch = batch_for_shader(shader, 'TRIS', {"pos": coords})
if _handle_surface is not None:
bpy.types.SpaceView3D.draw_handler_remove(_handle_surface, 'WINDOW')
_handle_surface = bpy.types.SpaceView3D.draw_handler_add(
draw_surface, (batch, shader), 'WINDOW', 'POST_VIEW')
elif _handle_surface is not None:
bpy.types.SpaceView3D.draw_handler_remove(_handle_surface, 'WINDOW')
_handle_surface = None
_handle_analemmas = None
def analemmas_update(self, context):
global _handle_analemmas
if self.show_analemmas:
coords = []
indices = []
coord_offset = 0
for h in range(24):
analemma_verts = calc_analemma(context, h)
coords.extend(analemma_verts)
for i in range(len(analemma_verts) - 1):
indices.append((coord_offset + i,
coord_offset + i+1))
coord_offset += len(analemma_verts)
shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
batch = batch_for_shader(shader, 'LINES',
{"pos": coords}, indices=indices)
if _handle_analemmas is not None:
bpy.types.SpaceView3D.draw_handler_remove(_handle_analemmas, 'WINDOW')
_handle_analemmas = bpy.types.SpaceView3D.draw_handler_add(
draw_analemmas, (batch, shader), 'WINDOW', 'POST_VIEW')
elif _handle_analemmas is not None:
bpy.types.SpaceView3D.draw_handler_remove(_handle_analemmas, 'WINDOW')
_handle_analemmas = None
...@@ -199,6 +199,14 @@ class SUNPOS_PT_Location(bpy.types.Panel): ...@@ -199,6 +199,14 @@ class SUNPOS_PT_Location(bpy.types.Panel):
col.prop(sp, "north_offset") col.prop(sp, "north_offset")
col.separator() col.separator()
if p.show_surface or p.show_analemmas:
col = flow.column(align=True)
if p.show_surface:
col.prop(sp, "show_surface", toggle=True)
if p.show_analemmas:
col.prop(sp, "show_analemmas", toggle=True)
col.separator()
if p.show_az_el: if p.show_az_el:
col = flow.column(align=True) col = flow.column(align=True)
split = col.split(factor=0.4, align=True) split = col.split(factor=0.4, align=True)
...@@ -216,6 +224,7 @@ class SUNPOS_PT_Location(bpy.types.Panel): ...@@ -216,6 +224,7 @@ class SUNPOS_PT_Location(bpy.types.Panel):
col = flow.column() col = flow.column()
col.prop(sp, "sun_distance") col.prop(sp, "sun_distance")
col.separator()
class SUNPOS_PT_Time(bpy.types.Panel): class SUNPOS_PT_Time(bpy.types.Panel):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment