mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
typing
This commit is contained in:
@@ -59,10 +59,10 @@ class SolarDecorator:
|
||||
shader.uniform_float("color", color)
|
||||
batch.draw(shader)
|
||||
|
||||
def draw_text(self, context):
|
||||
def draw_text(self, context: bpy.types.Context) -> None:
|
||||
self.addon_prefs = tool.Blender.get_addon_preferences()
|
||||
|
||||
props = bpy.context.scene.BIMSolarProperties
|
||||
props = tool.Blender.get_solar_props()
|
||||
origin = Matrix.Translation(props.sun_path_origin)
|
||||
location = origin @ (props.sun_position * 1.05)
|
||||
|
||||
@@ -76,7 +76,8 @@ class SolarDecorator:
|
||||
grid_north_p = origin @ angle @ (Vector((0, 0.8, 0)) * props.sun_path_size)
|
||||
self.draw_text_at_position(context, "True North", grid_north_p)
|
||||
|
||||
def draw_text_at_position(self, context, text, position):
|
||||
def draw_text_at_position(self, context: bpy.types.Context, text: str, position: Vector) -> None:
|
||||
assert context.region and context.region_data
|
||||
coords_2d = location_3d_to_region_2d(context.region, context.region_data, position)
|
||||
if not coords_2d:
|
||||
return
|
||||
@@ -87,7 +88,8 @@ class SolarDecorator:
|
||||
blf.position(self.font_id, co[0], co[1], 0)
|
||||
blf.draw(self.font_id, line)
|
||||
|
||||
def draw_geometry(self, context):
|
||||
def draw_geometry(self, context: bpy.types.Context) -> None:
|
||||
assert context.region
|
||||
self.addon_prefs = tool.Blender.get_addon_preferences()
|
||||
decorator_color_special = self.addon_prefs.decorator_color_special
|
||||
decorator_color_error = self.addon_prefs.decorator_color_error
|
||||
@@ -131,7 +133,7 @@ class SolarDecorator:
|
||||
|
||||
self.shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
|
||||
|
||||
props = bpy.context.scene.BIMSolarProperties
|
||||
props = tool.Blender.get_solar_props()
|
||||
|
||||
origin = Matrix.Translation(props.sun_path_origin)
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ class ExportOBJ(bpy.types.Operator):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.radiance_exporter_properties
|
||||
props = tool.Blender.get_radiance_exporter_props()
|
||||
if not props.should_load_from_memory and not props.ifc_file:
|
||||
cls.poll_message_set("Select an IFC file or use 'load from memory' if it's loaded in Bonsai.")
|
||||
return False
|
||||
@@ -66,10 +66,11 @@ class ExportOBJ(bpy.types.Operator):
|
||||
|
||||
def execute(self, context):
|
||||
# Get the output directory
|
||||
should_load_from_memory = context.scene.radiance_exporter_properties.should_load_from_memory
|
||||
output_dir = context.scene.radiance_exporter_properties.output_dir
|
||||
props = tool.Blender.get_radiance_exporter_props()
|
||||
should_load_from_memory = props.should_load_from_memory
|
||||
output_dir = props.output_dir
|
||||
|
||||
context.scene.radiance_exporter_properties.is_exporting = True
|
||||
props.is_exporting = True
|
||||
|
||||
# Conversion from IFC to OBJ
|
||||
# Settings for obj
|
||||
@@ -86,7 +87,7 @@ class ExportOBJ(bpy.types.Operator):
|
||||
ifc_file = tool.Ifc.get()
|
||||
|
||||
else:
|
||||
ifc_file_path = context.scene.radiance_exporter_properties.ifc_file
|
||||
ifc_file_path = props.ifc_file
|
||||
ifc_file = ifcopenshell.open(ifc_file_path)
|
||||
|
||||
obj_file_path = os.path.join(output_dir, "model.obj")
|
||||
@@ -121,7 +122,7 @@ class ExportOBJ(bpy.types.Operator):
|
||||
break
|
||||
|
||||
serialiser.finalize()
|
||||
context.scene.radiance_exporter_properties.is_exporting = False
|
||||
props.is_exporting = False
|
||||
|
||||
self.report({"INFO"}, "Exported OBJ file to: {}".format(obj_file_path))
|
||||
|
||||
@@ -141,9 +142,10 @@ class RadianceRender(bpy.types.Operator):
|
||||
return {"CANCELLED"}
|
||||
|
||||
print("Starting Radiance rendering process...")
|
||||
props = context.scene.radiance_exporter_properties
|
||||
props = tool.Blender.get_radiance_exporter_props()
|
||||
resolution_x, resolution_y = props.radiance_resolution_x, props.radiance_resolution_y
|
||||
|
||||
assert context.scene
|
||||
context.scene.render.resolution_x = resolution_x
|
||||
context.scene.render.resolution_y = resolution_y
|
||||
|
||||
@@ -172,8 +174,9 @@ class RadianceRender(bpy.types.Operator):
|
||||
|
||||
obj_file_path = os.path.join(output_dir, "model.obj")
|
||||
|
||||
sun_props = context.scene.BIMSolarProperties
|
||||
sun_pos_props = context.scene.sun_pos_properties
|
||||
sun_props = tool.Blender.get_solar_props()
|
||||
sun_pos_props = tool.Blender.get_sun_props()
|
||||
assert sun_pos_props
|
||||
sky_file_path = os.path.join(output_dir, "sky.rad")
|
||||
# latitude = sun_props.latitude
|
||||
# longitude = sun_props.longitude
|
||||
@@ -331,7 +334,7 @@ ground_glow source ground
|
||||
# f.write("skyfunc glow ground_glow\n0\n0\n4 1.4 .9 .6 0\n")
|
||||
# f.write("ground_glow source ground\n0\n0\n4 0 0 -1 180\n")
|
||||
|
||||
props = context.scene.radiance_exporter_properties
|
||||
props = tool.Blender.get_radiance_exporter_props()
|
||||
|
||||
data = props.get_mappings_dict()
|
||||
|
||||
@@ -458,7 +461,7 @@ ground_glow source ground
|
||||
return {"FINISHED"}
|
||||
|
||||
def get_active_camera(self, context):
|
||||
props = context.scene.radiance_exporter_properties
|
||||
props = tool.Blender.get_radiance_exporter_props()
|
||||
if props.use_active_camera:
|
||||
return context.scene.camera
|
||||
else:
|
||||
@@ -475,8 +478,7 @@ ground_glow source ground
|
||||
return (position.x, position.y, position.z), (direction.x, direction.y, direction.z)
|
||||
|
||||
def getResolution(self, context):
|
||||
scene = context.scene
|
||||
props = scene.radiance_exporter_properties
|
||||
props = tool.Blender.get_radiance_exporter_props()
|
||||
resolution_x = props.radiance_resolution_x
|
||||
resolution_y = props.radiance_resolution_y
|
||||
return resolution_x, resolution_y
|
||||
@@ -505,7 +507,7 @@ class ImportTrueNorth(bpy.types.Operator):
|
||||
return SolarData.data["true_north"] is not None
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.BIMSolarProperties
|
||||
props = tool.Blender.get_solar_props()
|
||||
for context in tool.Ifc.get().by_type("IfcGeometricRepresentationContext", include_subtypes=False):
|
||||
if not context.TrueNorth:
|
||||
continue
|
||||
@@ -521,7 +523,7 @@ class ImportLatLong(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.BIMSolarProperties
|
||||
props = tool.Blender.get_solar_props()
|
||||
site = tool.Ifc.get().by_id(int(props.sites))
|
||||
if site.RefLatitude and site.RefLongitude:
|
||||
props.latitude = ifcopenshell.util.geolocation.dms2dd(*site.RefLatitude)
|
||||
@@ -536,8 +538,9 @@ class MoveSunPathTo3DCursor(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.BIMSolarProperties
|
||||
props.sun_path_origin = bpy.context.scene.cursor.location
|
||||
props = tool.Blender.get_solar_props()
|
||||
assert context.scene
|
||||
props.sun_path_origin = context.scene.cursor.location
|
||||
tool.Blender.update_viewport()
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -557,7 +560,7 @@ class ViewFromSun(bpy.types.Operator):
|
||||
camera.data.ortho_scale = 100 # The default of 6m is too small
|
||||
context.scene.collection.objects.link(camera)
|
||||
tool.Blender.activate_camera(camera)
|
||||
props = context.scene.BIMSolarProperties
|
||||
props = tool.Blender.get_solar_props()
|
||||
props.hour = props.hour # Just to refresh camera position
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -568,7 +571,7 @@ class RefreshIFCMaterials(bpy.types.Operator):
|
||||
bl_description = "Refresh the list of IFC materials for mapping"
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.radiance_exporter_properties
|
||||
props = tool.Blender.get_radiance_exporter_props()
|
||||
ifc_file: ifcopenshell.file
|
||||
ifc_file = tool.Ifc.get() if props.should_load_from_memory else ifcopenshell.open(props.ifc_file)
|
||||
|
||||
@@ -616,7 +619,7 @@ class UnmapMaterial(bpy.types.Operator):
|
||||
material_index: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.radiance_exporter_properties
|
||||
props = tool.Blender.get_radiance_exporter_props()
|
||||
material = props.materials[self.material_index]
|
||||
props.unmap_material(material.name)
|
||||
return {"FINISHED"}
|
||||
@@ -633,7 +636,7 @@ class RADIANCE_OT_select_camera(bpy.types.Operator):
|
||||
return context.object is not None and context.object.type == "CAMERA"
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.radiance_exporter_properties
|
||||
props = tool.Blender.get_radiance_exporter_props()
|
||||
props.selected_camera = context.object
|
||||
props.use_active_camera = False
|
||||
return {"FINISHED"}
|
||||
@@ -648,7 +651,7 @@ class RADIANCE_OT_export_material_mappings(bpy.types.Operator, ExportHelper):
|
||||
filter_glob: bpy.props.StringProperty(default="*.json", options={"HIDDEN"})
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.radiance_exporter_properties
|
||||
props = tool.Blender.get_radiance_exporter_props()
|
||||
mappings = {}
|
||||
|
||||
for material in props.materials:
|
||||
@@ -674,7 +677,7 @@ class RADIANCE_OT_import_material_mappings(bpy.types.Operator, ImportHelper):
|
||||
filename_ext = ".json"
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.radiance_exporter_properties
|
||||
props = tool.Blender.get_radiance_exporter_props()
|
||||
props.import_mappings(self.filepath)
|
||||
self.report({"INFO"}, f"Material mappings imported from {self.filepath}")
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -22,6 +22,7 @@ import tzfpy
|
||||
import json
|
||||
import datetime
|
||||
import bonsai.tool as tool
|
||||
from typing import TYPE_CHECKING, Literal, Union
|
||||
from math import radians, pi
|
||||
from mathutils import Euler, Vector, Matrix, Quaternion
|
||||
from bpy.props import (
|
||||
@@ -42,66 +43,78 @@ from bonsai.bim.module.light.decorator import SolarDecorator
|
||||
sun_position = tool.Blender.get_sun_position_addon()
|
||||
|
||||
with open(os.path.join(os.path.dirname(__file__), "spectraldb.json"), "r") as f:
|
||||
spectraldb = json.load(f)
|
||||
spectraldb: dict[str, dict[str, str]] = json.load(f)
|
||||
|
||||
|
||||
def get_sites(self, context):
|
||||
def get_sites(self: "BIMSolarProperties", context: bpy.types.Context) -> tool.Blender.BLENDER_ENUM_ITEMS:
|
||||
if not SolarData.is_loaded:
|
||||
SolarData.load()
|
||||
return SolarData.data["sites"]
|
||||
|
||||
|
||||
def update_latlong(self, context):
|
||||
def update_latlong(self: "BIMSolarProperties", context: bpy.types.Context) -> None:
|
||||
update_sun_path(self)
|
||||
|
||||
|
||||
def update_hourminute(self, context):
|
||||
def update_hourminute(self: "BIMSolarProperties", context: bpy.types.Context) -> None:
|
||||
update_sun_path(self)
|
||||
|
||||
|
||||
def update_date(self, context):
|
||||
def update_date(self: "BIMSolarProperties", context: bpy.types.Context) -> None:
|
||||
update_sun_path(self)
|
||||
|
||||
|
||||
def update_true_north(self, context):
|
||||
def update_true_north(self: "BIMSolarProperties", context: bpy.types.Context) -> None:
|
||||
update_sun_path(self)
|
||||
|
||||
|
||||
def update_sun_path_size(self, context):
|
||||
def update_sun_path_size(self: "BIMSolarProperties", context: bpy.types.Context) -> None:
|
||||
update_sun_path(self)
|
||||
|
||||
|
||||
def update_shadow_mode(self, context):
|
||||
def update_shadow_mode(self: "BIMSolarProperties", context: bpy.types.Context) -> None:
|
||||
assert context.scene
|
||||
if self.shadow_mode == "SHADING":
|
||||
update_sun_path(self)
|
||||
context.scene.render.engine = "BLENDER_WORKBENCH"
|
||||
assert context.scene.display
|
||||
assert context.scene.display.shading
|
||||
context.scene.display.shading.light = "FLAT"
|
||||
context.scene.display.shading.show_shadows = True
|
||||
context.scene.display.shading.show_object_outline = True
|
||||
context.scene.display.shadow_focus = 1.0
|
||||
assert context.scene.view_settings
|
||||
context.scene.view_settings.view_transform = "Standard" # Preserve shading colours
|
||||
space = tool.Blender.get_view3d_space()
|
||||
assert space
|
||||
space.shading.type = "RENDERED"
|
||||
elif self.shadow_mode == "RENDERING":
|
||||
if context.scene.sun_pos_properties.sun_object is None:
|
||||
sun_props = tool.Blender.get_sun_props()
|
||||
assert sun_props
|
||||
if sun_props.sun_object is None:
|
||||
bpy.ops.object.light_add(type="SUN", radius=1, align="WORLD", location=(0, 0, 0), scale=(1, 1, 1))
|
||||
bpy.ops.object.move_to_collection(collection_index=0)
|
||||
context.scene.sun_pos_properties.sun_object = bpy.context.active_object
|
||||
sun_props.sun_object = bpy.context.active_object
|
||||
update_sun_path(self)
|
||||
context.scene.render.engine = "BLENDER_EEVEE_NEXT"
|
||||
assert context.scene.display
|
||||
assert context.scene.display.shading
|
||||
context.scene.display.shading.light = "FLAT"
|
||||
context.scene.display.shading.show_shadows = True
|
||||
context.scene.display.shading.show_object_outline = True
|
||||
context.scene.display.shadow_focus = 1.0
|
||||
assert context.scene.view_settings
|
||||
context.scene.view_settings.view_transform = "Standard" # Preserve shading colours
|
||||
space = tool.Blender.get_view3d_space()
|
||||
assert space
|
||||
space.shading.type = "RENDERED"
|
||||
else:
|
||||
space = tool.Blender.get_view3d_space()
|
||||
assert space
|
||||
space.shading.type = "SOLID"
|
||||
|
||||
|
||||
def update_display_sun_path(self, context):
|
||||
def update_display_sun_path(self: "BIMSolarProperties", context: bpy.types.Context) -> None:
|
||||
if self.display_sun_path:
|
||||
update_sun_path(self)
|
||||
SolarDecorator.install(bpy.context)
|
||||
@@ -109,20 +122,25 @@ def update_display_sun_path(self, context):
|
||||
SolarDecorator.uninstall()
|
||||
|
||||
|
||||
def update_resolution(self, context):
|
||||
def update_resolution(self: "RadianceExporterProperties", context: bpy.types.Context) -> None:
|
||||
assert context.scene
|
||||
context.scene.render.resolution_x = self.radiance_resolution_x
|
||||
context.scene.render.resolution_y = self.radiance_resolution_y
|
||||
|
||||
|
||||
def update_sun_path(self):
|
||||
def update_sun_path(self: "BIMSolarProperties") -> None:
|
||||
if not SolarData.is_loaded:
|
||||
SolarData.load()
|
||||
|
||||
if (sun_position := SolarData.data["sun_position"]) is None:
|
||||
return
|
||||
|
||||
props = bpy.context.scene.BIMSolarProperties
|
||||
sun_props = bpy.context.scene.sun_pos_properties
|
||||
if TYPE_CHECKING:
|
||||
import sun_position
|
||||
|
||||
props = tool.Blender.get_solar_props()
|
||||
sun_props = tool.Blender.get_sun_props()
|
||||
assert sun_props
|
||||
|
||||
sun_props.sun_distance = self.sun_path_size
|
||||
sun_props.latitude = self.latitude
|
||||
@@ -166,6 +184,8 @@ def update_sun_path(self):
|
||||
props.elevation = elevation
|
||||
props.UTC_zone = zone
|
||||
|
||||
assert bpy.context.scene
|
||||
assert bpy.context.scene.display
|
||||
if sun_vector.z < 0:
|
||||
bpy.context.scene.display.light_direction = mat @ Vector((0, 0, 1))
|
||||
else:
|
||||
@@ -173,6 +193,7 @@ def update_sun_path(self):
|
||||
SolarData.data["sun"] = sun_vector
|
||||
|
||||
if obj := bpy.data.objects.get("SunPathCamera"):
|
||||
assert isinstance(obj.data, bpy.types.Camera)
|
||||
obj.matrix_world.translation = sun_vector
|
||||
z180_quaternion = Quaternion((0, 0, 1), radians(180))
|
||||
obj.rotation_mode = "QUATERNION"
|
||||
@@ -181,25 +202,31 @@ def update_sun_path(self):
|
||||
|
||||
|
||||
class RadianceMaterial(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
style_id: StringProperty(name="Style ID")
|
||||
category: StringProperty(name="Category")
|
||||
subcategory: StringProperty(name="Subcategory")
|
||||
is_mapped: BoolProperty(name="Is Mapped", default=False)
|
||||
color: FloatVectorProperty(name="Color", subtype="COLOR", default=(1.0, 1.0, 1.0), min=0.0, max=1.0, size=3)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
style_id: str
|
||||
category: str
|
||||
subcategory: str
|
||||
is_mapped: bool
|
||||
color: tuple[float, float, float]
|
||||
|
||||
|
||||
class RadianceExporterProperties(PropertyGroup):
|
||||
|
||||
def update_output_dir(self, context):
|
||||
def update_output_dir(self, context) -> None:
|
||||
if self.output_dir:
|
||||
self.output_dir = bpy.path.abspath(self.output_dir)
|
||||
|
||||
def update_ifc_file(self, context):
|
||||
def update_ifc_file(self, context) -> None:
|
||||
if self.ifc_file:
|
||||
self.ifc_file = bpy.path.abspath(self.ifc_file)
|
||||
|
||||
def add_material_mapping(self, style_id, style_name):
|
||||
def add_material_mapping(self, style_id: str, style_name: str) -> RadianceMaterial:
|
||||
item = self.materials.add()
|
||||
item.name = style_name
|
||||
item.style_id = style_id
|
||||
@@ -208,7 +235,7 @@ class RadianceExporterProperties(PropertyGroup):
|
||||
item.color = (1.0, 1.0, 1.0) # Default white
|
||||
return item
|
||||
|
||||
def import_mappings(self, filepath):
|
||||
def import_mappings(self, filepath: str) -> None:
|
||||
with open(filepath, "r") as f:
|
||||
mappings = json.load(f)
|
||||
|
||||
@@ -225,10 +252,10 @@ class RadianceExporterProperties(PropertyGroup):
|
||||
new_material.subcategory = mapping["subcategory"]
|
||||
new_material.is_mapped = True
|
||||
|
||||
def get_material_mapping(self, style_name):
|
||||
def get_material_mapping(self, style_name: str) -> Union[RadianceMaterial, None]:
|
||||
return next((item for item in self.materials if item.name == style_name), None)
|
||||
|
||||
def set_material_mapping(self, style_id, style_name, category, subcategory):
|
||||
def set_material_mapping(self, style_id: str, style_name: str, category: str, subcategory: str) -> None:
|
||||
item = self.get_material_mapping(style_name)
|
||||
if item:
|
||||
item.category = category
|
||||
@@ -238,14 +265,14 @@ class RadianceExporterProperties(PropertyGroup):
|
||||
self.materials[-1].category = category
|
||||
self.materials[-1].subcategory = subcategory
|
||||
|
||||
def get_mappings_dict(self):
|
||||
def get_mappings_dict(self) -> dict[str, tuple[str, str]]:
|
||||
return {
|
||||
item.style_id: (item.category, item.subcategory)
|
||||
for item in self.materials
|
||||
if item.category and item.subcategory
|
||||
}
|
||||
|
||||
def unmap_material(self, style_name):
|
||||
def unmap_material(self, style_name: str) -> None:
|
||||
item = self.get_material_mapping(style_name)
|
||||
if item:
|
||||
item.category = ""
|
||||
@@ -273,7 +300,7 @@ class RadianceExporterProperties(PropertyGroup):
|
||||
("Glass", "Glass", ""),
|
||||
]
|
||||
|
||||
def update_material_mapping(self, context):
|
||||
def update_material_mapping(self, context: bpy.types.Context) -> None:
|
||||
if self.active_material_index >= 0 and self.active_material_index < len(self.materials):
|
||||
active_material = self.materials[self.active_material_index]
|
||||
active_material.category = self.category
|
||||
@@ -285,7 +312,7 @@ class RadianceExporterProperties(PropertyGroup):
|
||||
items=categories, name="Category", description="Material category", update=update_material_mapping
|
||||
)
|
||||
|
||||
def get_subcategories(self, context):
|
||||
def get_subcategories(self, context: bpy.types.Context) -> tool.Blender.BLENDER_ENUM_ITEMS:
|
||||
global SUBCATEGORIES_ENUM_ITEMS
|
||||
if self.category in spectraldb:
|
||||
SUBCATEGORIES_ENUM_ITEMS = [(k, k, "") for k in spectraldb[self.category].keys()]
|
||||
@@ -390,6 +417,27 @@ class RadianceExporterProperties(PropertyGroup):
|
||||
poll=lambda self, object: object.type == "CAMERA",
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
is_exporting: bool
|
||||
category: str
|
||||
subcategory: str
|
||||
materials: bpy.types.bpy_prop_collection_idprop[RadianceMaterial]
|
||||
active_material_index: int
|
||||
should_load_from_memory: bool
|
||||
radiance_resolution_x: int
|
||||
radiance_resolution_y: int
|
||||
output_dir: str
|
||||
ifc_file: str
|
||||
radiance_quality: Literal["LOW", "MEDIUM", "HIGH"]
|
||||
radiance_detail: Literal["LOW", "MEDIUM", "HIGH"]
|
||||
radiance_variability: Literal["LOW", "MEDIUM", "HIGH"]
|
||||
output_file_name: str
|
||||
output_file_format: Literal["HDR"]
|
||||
use_hdr: bool
|
||||
choose_hdr_image: Literal["Noon"]
|
||||
use_active_camera: bool
|
||||
selected_camera: Union[bpy.types.Object, None]
|
||||
|
||||
|
||||
class BIMSolarProperties(PropertyGroup):
|
||||
sites: EnumProperty(items=get_sites, name="Sites")
|
||||
@@ -436,3 +484,23 @@ class BIMSolarProperties(PropertyGroup):
|
||||
description="Displays analemmas and sun position",
|
||||
update=update_display_sun_path,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
sites: str
|
||||
latitude: float
|
||||
longitude: float
|
||||
timezone: str
|
||||
true_north: float
|
||||
year: int
|
||||
month: int
|
||||
day: int
|
||||
hour: int
|
||||
minute: int
|
||||
sun_position: Vector
|
||||
sun_path_origin: Vector
|
||||
sun_path_size: float
|
||||
azimuth: float
|
||||
elevation: float
|
||||
UTC_zone: float
|
||||
shadow_mode: Literal["NONE", "SHADING", "RENDERING"]
|
||||
display_sun_path: bool
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
from typing import TYPE_CHECKING
|
||||
from bonsai.bim.module.light.data import SolarData
|
||||
|
||||
|
||||
@@ -33,10 +34,9 @@ class BIM_PT_radiance_exporter(bpy.types.Panel):
|
||||
bl_parent_id = "BIM_PT_tab_lighting"
|
||||
|
||||
def draw(self, context):
|
||||
assert self.layout
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
|
||||
props = scene.radiance_exporter_properties
|
||||
props = tool.Blender.get_radiance_exporter_props()
|
||||
|
||||
if tool.Ifc.get():
|
||||
row = self.layout.row()
|
||||
@@ -145,11 +145,15 @@ class BIM_PT_solar(bpy.types.Panel):
|
||||
if not SolarData.is_loaded:
|
||||
SolarData.load()
|
||||
|
||||
assert self.layout
|
||||
if (sun_position := SolarData.data["sun_position"]) is None:
|
||||
self.layout.label(text="Enable 'Sun Position' Add-on To Continue", icon="ERROR")
|
||||
return
|
||||
|
||||
props = context.scene.BIMSolarProperties
|
||||
if TYPE_CHECKING:
|
||||
import sun_position
|
||||
|
||||
props = tool.Blender.get_solar_props()
|
||||
|
||||
if SolarData.data["sites"]:
|
||||
row = self.layout.row(align=True)
|
||||
@@ -159,7 +163,7 @@ class BIM_PT_solar(bpy.types.Panel):
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="No Sites With Lat/Longs Found", icon="ERROR")
|
||||
|
||||
sun_props = context.scene.sun_pos_properties
|
||||
sun_props = tool.Blender.get_sun_props()
|
||||
|
||||
row = self.layout.row()
|
||||
row.prop(sun_props, "coordinates", icon="URL")
|
||||
@@ -243,7 +247,9 @@ class BIM_PT_solar(bpy.types.Panel):
|
||||
row.prop(context.scene.display.shading, "shadow_intensity", text="Shadow Intensity")
|
||||
elif props.shadow_mode == "RENDERING":
|
||||
row = self.layout.row()
|
||||
row.prop(context.scene.sun_pos_properties.sun_object.data, "energy", text="Sun Intensity")
|
||||
sun_props = tool.Blender.get_sun_props()
|
||||
assert sun_props
|
||||
row.prop(sun_props.sun_object.data, "energy", text="Sun Intensity")
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
row.operator("bim.view_from_sun", icon="LIGHT_HEMI")
|
||||
|
||||
@@ -54,13 +54,15 @@ from typing import (
|
||||
from collections.abc import Iterable, Callable, Generator, Sequence, Sized
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from sun_position.properties import SunPosProperties
|
||||
import bpy.stub_internal.rna_enums as rna_enums
|
||||
from bonsai.bim.prop import BIMProperties, BIMObjectProperties
|
||||
from bonsai.bim.module.attribute.prop import BIMAttributeProperties
|
||||
from bonsai.bim.module.csv.prop import CsvProperties
|
||||
from bonsai.bim.module.constraint.prop import BIMConstraintProperties, BIMObjectConstraintProperties
|
||||
from bonsai.bim.module.csv.prop import CsvProperties
|
||||
from bonsai.bim.module.diff.prop import DiffProperties
|
||||
from bonsai.bim.module.group.prop import BIMGroupProperties
|
||||
from bonsai.bim.module.light.prop import BIMSolarProperties, RadianceExporterProperties
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
@@ -1495,6 +1497,11 @@ class Blender(bonsai.core.tool.Blender):
|
||||
|
||||
return sun_position
|
||||
|
||||
@classmethod
|
||||
def get_sun_props(cls) -> Union[SunPosProperties, None]:
|
||||
assert (scene := bpy.context.scene)
|
||||
return getattr(scene, "sun_pos_properties", None)
|
||||
|
||||
@classmethod
|
||||
def scale_font_size(cls, size):
|
||||
default_dpi = 72
|
||||
@@ -1694,6 +1701,16 @@ class Blender(bonsai.core.tool.Blender):
|
||||
def get_object_attribute_props(cls, obj: bpy.types.Object) -> BIMAttributeProperties:
|
||||
return obj.BIMAttributeProperties
|
||||
|
||||
@classmethod
|
||||
def get_solar_props(cls) -> BIMSolarProperties:
|
||||
assert (scene := bpy.context.scene)
|
||||
return scene.BIMSolarProperties
|
||||
|
||||
@classmethod
|
||||
def get_radiance_exporter_props(cls) -> RadianceExporterProperties:
|
||||
assert (scene := bpy.context.scene)
|
||||
return scene.radiance_exporter_properties
|
||||
|
||||
@classmethod
|
||||
def get_ifc_definition_id(cls, obj: IFC_CONNECTED_TYPE) -> int:
|
||||
if isinstance(obj, bpy.types.Object):
|
||||
|
||||
Reference in New Issue
Block a user