[Bf-extensions-cvs] [29a67357] master: Sun Position: add Show Surface and Show Analemmas options

Eduardo Schilling noreply at git.blender.org
Sun Jan 8 14:40:20 CET 2023


Commit: 29a67357a059594489e4929ff61a28dc81e859b0
Author: Eduardo Schilling
Date:   Sat Jan 7 17:33:26 2023 +0100
Branches: master
https://developer.blender.org/rBA29a67357a059594489e4929ff61a28dc81e859b0

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

===================================================================

M	sun_position/__init__.py
M	sun_position/properties.py
M	sun_position/sun_calc.py
M	sun_position/ui_sun.py

===================================================================

diff --git a/sun_position/__init__.py b/sun_position/__init__.py
index 0ec83bdb..95bf8ff4 100644
--- a/sun_position/__init__.py
+++ b/sun_position/__init__.py
@@ -16,7 +16,7 @@
 bl_info = {
     "name": "Sun Position",
     "author": "Michael Martin",
-    "version": (3, 1, 3),
+    "version": (3, 2, 0),
     "blender": (3, 0, 0),
     "location": "World > Sun Position",
     "description": "Show sun position with objects and/or sky texture",
@@ -48,6 +48,8 @@ register_classes, unregister_classes = bpy.utils.register_classes_factory(
 @persistent
 def sun_scene_handler(scene):
     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
 
 
diff --git a/sun_position/properties.py b/sun_position/properties.py
index 5d8254e4..214fdb4e 100644
--- a/sun_position/properties.py
+++ b/sun_position/properties.py
@@ -5,7 +5,7 @@ from bpy.types import AddonPreferences, PropertyGroup
 from bpy.props import (StringProperty, EnumProperty, IntProperty,
                        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 math import pi
@@ -53,6 +53,18 @@ class SunPosProperties(PropertyGroup):
         soft_min=-pi, soft_max=pi, step=10.0, default=0.0,
         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(
         name="Latitude",
         description="Latitude: (+) Northern (-) Southern",
@@ -186,7 +198,6 @@ class SunPosProperties(PropertyGroup):
         soft_min=1.0, soft_max=24.0, step=1.0, default=23.0,
         update=sun_update)
 
-
 ############################################################################
 # Preference panel properties
 ############################################################################
@@ -211,6 +222,18 @@ class SunPosAddonPreferences(AddonPreferences):
         default=True,
         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(
         name="Refraction",
         description="Show sun refraction choice",
@@ -244,6 +267,8 @@ class SunPosAddonPreferences(AddonPreferences):
         flow.prop(self, "show_time_place")
         flow.prop(self, "show_dms")
         flow.prop(self, "show_north")
+        flow.prop(self, "show_surface")
+        flow.prop(self, "show_analemmas")
         flow.prop(self, "show_refraction")
         flow.prop(self, "show_az_el")
         flow.prop(self, "show_daylight_savings")
diff --git a/sun_position/sun_calc.py b/sun_position/sun_calc.py
index fc4e0452..a2e44387 100644
--- a/sun_position/sun_calc.py
+++ b/sun_position/sun_calc.py
@@ -2,6 +2,8 @@
 
 import bpy
 from bpy.app.handlers import persistent
+import gpu
+from gpu_extras.batch import batch_for_shader
 from mathutils import Euler, Vector
 import math
 from math import degrees, radians, pi
@@ -51,6 +53,10 @@ sun = SunInfo()
 def sun_update(self, context):
     update_time(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):
@@ -563,3 +569,107 @@ def mean_anomaly_sun(t):
 
 def eccentricity_earth_orbit(t):
     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
diff --git a/sun_position/ui_sun.py b/sun_position/ui_sun.py
index c6eebc33..e2d99f0b 100644
--- a/sun_position/ui_sun.py
+++ b/sun_position/ui_sun.py
@@ -199,6 +199,14 @@ class SUNPOS_PT_Location(bpy.types.Panel):
             col.prop(sp, "north_offset")
             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:
             col = flow.column(align=True)
             split = col.split(factor=0.4, align=True)
@@ -216,6 +224,7 @@ class SUNPOS_PT_Location(bpy.types.Panel):
 
         col = flow.column()
         col.prop(sp, "sun_distance")
+        col.separator()
 
 
 class SUNPOS_PT_Time(bpy.types.Panel):



More information about the Bf-extensions-cvs mailing list