From 3b8b4c1566cb112620aeea4151d2931ea7e1df2b Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Fri, 1 Aug 2025 19:22:14 +0500 Subject: [PATCH] typing --- .../bonsai/bim/module/covetool/operator.py | 19 +++++---- src/bonsai/bonsai/bim/module/covetool/prop.py | 40 +++++++++++++++++-- src/bonsai/bonsai/bim/module/covetool/ui.py | 20 ++++++++-- src/bonsai/bonsai/bim/module/drawing/ui.py | 13 +++++- src/bonsai/bonsai/bim/module/light/list.py | 18 ++++++++- src/bonsai/bonsai/bim/module/search/ui.py | 40 +++++++++++++++++-- src/bonsai/bonsai/bim/operator.py | 5 +++ src/bonsai/bonsai/core/bsdd.py | 8 ++-- src/bonsai/bonsai/tool/blender.py | 6 +++ src/bonsai/bonsai/tool/bsdd.py | 2 +- src/bonsai/bonsai/tool/drawing.py | 4 +- 11 files changed, 145 insertions(+), 30 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/covetool/operator.py b/src/bonsai/bonsai/bim/module/covetool/operator.py index a11e836750..cccb164611 100644 --- a/src/bonsai/bonsai/bim/module/covetool/operator.py +++ b/src/bonsai/bonsai/bim/module/covetool/operator.py @@ -34,13 +34,14 @@ class Login(bpy.types.Operator): bl_options = {"REGISTER", "UNDO"} def execute(self, context): - token = api.login(context.scene.CoveToolProperties.username, context.scene.CoveToolProperties.password) + props = tool.Blender.get_covetool_props() + token = api.login(props.username, props.password) if token: - context.scene.CoveToolProperties.token = token + props.token = token projects = api.get_request("projects") for project in projects: - new_project = context.scene.CoveToolProperties.projects.add() + new_project = props.projects.add() new_project.name = project["name"] new_project.run_set = project["run_set"][0] new_project.url = project["url"] @@ -54,11 +55,10 @@ class RunSimpleAnalysis(bpy.types.Operator): bl_label = "Run Simple Analysis" def execute(self, context): - simple_analysis = context.scene.CoveToolProperties.simple_analysis + props = tool.Blender.get_covetool_props() + simple_analysis = props.simple_analysis data = { - "run": context.scene.CoveToolProperties.projects[ - context.scene.CoveToolProperties.active_project_index - ].run_set, + "run": props.projects[props.active_project_index].run_set, "si_units": simple_analysis.si_units, "building_height": simple_analysis.building_height, "roof_area": simple_analysis.roof_area, @@ -92,6 +92,7 @@ class RunAnalysis(bpy.types.Operator): bl_label = "Run Analysis" def execute(self, context): + props = tool.Blender.get_covetool_props() self.file = tool.Ifc.get() self.inputs = { "floors": [], @@ -104,9 +105,7 @@ class RunAnalysis(bpy.types.Operator): } self.parse_objects(context) data = { - "run": context.scene.CoveToolProperties.projects[ - context.scene.CoveToolProperties.active_project_index - ].run_set, + "run": props.projects[props.active_project_index].run_set, "source": "Bonsai", "rotation_angle": self.get_rotation_angle(), **self.inputs, diff --git a/src/bonsai/bonsai/bim/module/covetool/prop.py b/src/bonsai/bonsai/bim/module/covetool/prop.py index bb0cf6d585..06444de29f 100644 --- a/src/bonsai/bonsai/bim/module/covetool/prop.py +++ b/src/bonsai/bonsai/bim/module/covetool/prop.py @@ -16,15 +16,18 @@ # You should have received a copy of the GNU General Public License # along with Bonsai. If not, see . -import bpy.props -import bpy.types +import bpy +from typing import TYPE_CHECKING class CoveToolProject(bpy.types.PropertyGroup): - name: bpy.props.StringProperty(name="Name") run_set: bpy.props.StringProperty(name="Run Set") url: bpy.props.StringProperty(name="URL") + if TYPE_CHECKING: + run_set: str + url: set + class CoveToolSimpleAnalysis(bpy.types.PropertyGroup): si_units: bpy.props.BoolProperty(name="SI Units") @@ -49,6 +52,29 @@ class CoveToolSimpleAnalysis(bpy.types.PropertyGroup): window_area_s: bpy.props.StringProperty(name="Window Area S") window_area_se: bpy.props.StringProperty(name="Window Area SE") + if TYPE_CHECKING: + si_units: bool + building_height: str + roof_area: str + floor_area: str + skylight_area: str + wall_area_e: str + wall_area_ne: str + wall_area_n: str + wall_area_nw: str + wall_area_w: str + wall_area_sw: str + wall_area_s: str + wall_area_se: str + window_area_e: str + window_area_ne: str + window_area_n: str + window_area_nw: str + window_area_w: str + window_area_sw: str + window_area_s: str + window_area_se: str + class CoveToolProperties(bpy.types.PropertyGroup): username: bpy.props.StringProperty(name="Username") @@ -57,3 +83,11 @@ class CoveToolProperties(bpy.types.PropertyGroup): projects: bpy.props.CollectionProperty(name="Projects", type=CoveToolProject) active_project_index: bpy.props.IntProperty(name="Active Project Index") simple_analysis: bpy.props.PointerProperty(type=CoveToolSimpleAnalysis) + + if TYPE_CHECKING: + username: str + password: str + token: str + projects: bpy.types.bpy_prop_collection_idprop[CoveToolProject] + active_project_index: int + simple_analysis: CoveToolSimpleAnalysis diff --git a/src/bonsai/bonsai/bim/module/covetool/ui.py b/src/bonsai/bonsai/bim/module/covetool/ui.py index 38f35646d8..e26ac1338a 100644 --- a/src/bonsai/bonsai/bim/module/covetool/ui.py +++ b/src/bonsai/bonsai/bim/module/covetool/ui.py @@ -16,7 +16,13 @@ # You should have received a copy of the GNU General Public License # along with Bonsai. If not, see . +from __future__ import annotations import bpy.types +import bonsai.tool as tool +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from bonsai.bim.module.covetool.prop import CoveToolProperties, CoveToolProject class BIM_PT_covetool(bpy.types.Panel): @@ -32,8 +38,7 @@ class BIM_PT_covetool(bpy.types.Panel): layout = self.layout layout.use_property_split = True - scene = context.scene - props = scene.CoveToolProperties + props = tool.Blender.get_covetool_props() if not props.token: row = layout.row() @@ -81,7 +86,16 @@ class BIM_PT_covetool(bpy.types.Panel): class BIM_UL_covetool_projects(bpy.types.UIList): - def draw_item(self, context, layout, data, item, icon, active_data, active_propname): + def draw_item( + self, + context, + layout: bpy.types.UILayout, + data: CoveToolProperties, + item: CoveToolProject, + icon, + active_data, + active_propname, + ) -> None: ob = data if item: layout.prop(item, "name", text="", emboss=False) diff --git a/src/bonsai/bonsai/bim/module/drawing/ui.py b/src/bonsai/bonsai/bim/module/drawing/ui.py index 767eb07bce..9129bb48ab 100644 --- a/src/bonsai/bonsai/bim/module/drawing/ui.py +++ b/src/bonsai/bonsai/bim/module/drawing/ui.py @@ -32,7 +32,7 @@ from bonsai.bim.module.drawing.data import ( from typing import TYPE_CHECKING if TYPE_CHECKING: - from bonsai.bim.module.drawing.prop import DocProperties, Drawing + from bonsai.bim.module.drawing.prop import DocProperties, Drawing, Sheet class BIM_PT_camera(Panel): @@ -678,7 +678,16 @@ class BIM_UL_drawinglist(bpy.types.UIList): class BIM_UL_sheets(bpy.types.UIList): - def draw_item(self, context, layout, data, item, icon, active_data, active_propname): + def draw_item( + self, + context, + layout: bpy.types.UILayout, + data: DocProperties, + item: Sheet, + icon, + active_data, + active_propname, + ) -> None: if not item: layout.label(text="", translate=False) return diff --git a/src/bonsai/bonsai/bim/module/light/list.py b/src/bonsai/bonsai/bim/module/light/list.py index 0536284e7a..6eaa1f4c79 100644 --- a/src/bonsai/bonsai/bim/module/light/list.py +++ b/src/bonsai/bonsai/bim/module/light/list.py @@ -16,17 +16,31 @@ # You should have received a copy of the GNU General Public License # along with Bonsai. If not, see . - +from __future__ import annotations import bpy import json import os +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from bonsai.bim.module.light.prop import RadianceExporterProperties, RadianceMaterial with open(os.path.join(os.path.dirname(__file__), "spectraldb.json"), "r") as f: spectraldb = json.load(f) class MATERIAL_UL_radiance_materials(bpy.types.UIList): - def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): + def draw_item( + self, + context, + layout: bpy.types.UILayout, + data: RadianceExporterProperties, + item: RadianceMaterial, + icon, + active_data, + active_propname, + index, + ) -> None: if self.layout_type in {"DEFAULT", "COMPACT"}: row = layout.row(align=True) diff --git a/src/bonsai/bonsai/bim/module/search/ui.py b/src/bonsai/bonsai/bim/module/search/ui.py index a9254415e7..21c9d5f94b 100644 --- a/src/bonsai/bonsai/bim/module/search/ui.py +++ b/src/bonsai/bonsai/bim/module/search/ui.py @@ -16,11 +16,16 @@ # You should have received a copy of the GNU General Public License # along with Bonsai. If not, see . +from __future__ import annotations import bpy import bonsai.tool as tool import bonsai.bim.helper from bpy.types import Panel from bonsai.bim.module.search.data import SearchData, ColourByPropertyData, SelectSimilarData +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from bonsai.bim.module.search.prop import BIMSearchProperties, BIMColour, BIMFilterClasses, BIMFilterBuildingStoreys class BIM_PT_search(Panel): @@ -141,7 +146,16 @@ class BIM_PT_select_similar(Panel): class BIM_UL_colourscheme(bpy.types.UIList): - def draw_item(self, context, layout, data, item, icon, active_data, active_propname): + def draw_item( + self, + context, + layout: bpy.types.UILayout, + data: BIMSearchProperties, + item: BIMColour, + icon, + active_data, + active_propname, + ) -> None: if not item: return row = layout.row(align=True) @@ -153,7 +167,17 @@ class BIM_UL_colourscheme(bpy.types.UIList): class BIM_UL_ifc_class_filter(bpy.types.UIList): use_filter_linked: bpy.props.BoolProperty(name="Included", default=True, options=set(), description="Filter") - def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): + def draw_item( + self, + context, + layout: bpy.types.UILayout, + data: BIMSearchProperties, + item: BIMFilterClasses, + icon, + active_data, + active_propname, + index, + ) -> None: split = layout split.use_property_split = True split.use_property_decorate = False @@ -169,7 +193,17 @@ class BIM_UL_ifc_class_filter(bpy.types.UIList): class BIM_UL_ifc_building_storey_filter(bpy.types.UIList): use_filter_linked: bpy.props.BoolProperty(name="Included", default=True, options=set(), description="Filter") - def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): + def draw_item( + self, + context, + layout: bpy.types.UILayout, + data: BIMSearchProperties, + item: BIMFilterBuildingStoreys, + icon, + active_data, + active_propname, + index, + ) -> None: split = layout split.use_property_split = True split.use_property_decorate = False diff --git a/src/bonsai/bonsai/bim/operator.py b/src/bonsai/bonsai/bim/operator.py index f57c972eb1..e7fe1432b4 100644 --- a/src/bonsai/bonsai/bim/operator.py +++ b/src/bonsai/bonsai/bim/operator.py @@ -1033,6 +1033,11 @@ class BIM_OT_enum_property_search(bpy.types.Operator): identifiers: list[str] + if TYPE_CHECKING: + collection_names: bpy.types.bpy_prop_collection_idprop[StrProperty] + collection_identifiers: bpy.types.bpy_prop_collection_idprop[StrProperty] + collection_predefined_types: bpy.types.bpy_prop_collection_idprop[StrProperty] + def invoke(self, context, event): self.clear_collections() self.data = context.data diff --git a/src/bonsai/bonsai/core/bsdd.py b/src/bonsai/bonsai/core/bsdd.py index 34ff455091..1bec597f5d 100644 --- a/src/bonsai/bonsai/core/bsdd.py +++ b/src/bonsai/bonsai/core/bsdd.py @@ -26,12 +26,12 @@ if TYPE_CHECKING: import bonsai.tool as tool -def import_bsdd_classes(bsdd: type[tool.Bsdd], obj, obj_type) -> int: - return bsdd.import_classes(obj, obj_type) +def import_bsdd_classes(bsdd: type[tool.Bsdd], obj: str, obj_type: tool.Ifc.OBJECT_TYPE) -> None: + bsdd.import_classes(obj, obj_type) -def search_bsdd_properties(bsdd: type[tool.Bsdd], keyword: str, obj, obj_type) -> int: - return bsdd.import_properties(obj, obj_type, keyword) +def search_bsdd_properties(bsdd: type[tool.Bsdd], keyword: str, obj: str, obj_type: tool.Ifc.OBJECT_TYPE) -> None: + bsdd.import_properties(obj, obj_type, keyword) def load_bsdd(bsdd: type[tool.Bsdd]) -> None: diff --git a/src/bonsai/bonsai/tool/blender.py b/src/bonsai/bonsai/tool/blender.py index 3a183d19de..ead94fa6b6 100644 --- a/src/bonsai/bonsai/tool/blender.py +++ b/src/bonsai/bonsai/tool/blender.py @@ -59,6 +59,7 @@ if TYPE_CHECKING: from bonsai.bim.prop import BIMProperties, BIMObjectProperties from bonsai.bim.module.attribute.prop import BIMAttributeProperties from bonsai.bim.module.constraint.prop import BIMConstraintProperties, BIMObjectConstraintProperties + from bonsai.bim.module.covetool.prop import CoveToolProperties from bonsai.bim.module.csv.prop import CsvProperties from bonsai.bim.module.diff.prop import DiffProperties from bonsai.bim.module.fm.prop import BIMFMProperties @@ -1783,6 +1784,11 @@ class Blender(bonsai.core.tool.Blender): assert (scene := bpy.context.scene) return scene.BIMFMProperties # pyright: ignore[reportAttributeAccessIssue] + @classmethod + def get_covetool_props(cls) -> CoveToolProperties: + assert (scene := bpy.context.scene) + return scene.CoveToolProperties # pyright: ignore[reportAttributeAccessIssue] + @classmethod def get_ifc_definition_id(cls, obj: IFC_CONNECTED_TYPE) -> int: if isinstance(obj, bpy.types.Object): diff --git a/src/bonsai/bonsai/tool/bsdd.py b/src/bonsai/bonsai/tool/bsdd.py index e78edc2c0e..5c2e4652e7 100644 --- a/src/bonsai/bonsai/tool/bsdd.py +++ b/src/bonsai/bonsai/tool/bsdd.py @@ -306,7 +306,7 @@ class Bsdd(bonsai.core.tool.Bsdd): new.uri = bsdd_prop["uri"] @classmethod - def import_properties(cls, obj, obj_type, keyword) -> None: + def import_properties(cls, obj: str, obj_type: tool.Ifc.OBJECT_TYPE, keyword: str) -> None: props = cls.get_bsdd_props() props.properties.clear() pprops = tool.Pset.get_pset_props(obj, obj_type) diff --git a/src/bonsai/bonsai/tool/drawing.py b/src/bonsai/bonsai/tool/drawing.py index 337b817853..46310e291b 100644 --- a/src/bonsai/bonsai/tool/drawing.py +++ b/src/bonsai/bonsai/tool/drawing.py @@ -933,12 +933,12 @@ class Drawing(bonsai.core.tool.Drawing): camera_props.update_props = update_props + drawing_selected_states: dict[int, bool] = {} + @classmethod def import_drawings(cls) -> None: props = tool.Drawing.get_document_props() expanded_target_views = {d.target_view for d in props.drawings if not d.is_drawing and d.is_expanded} - if not hasattr(cls, "drawing_selected_states"): - cls.drawing_selected_states = {} cls.drawing_selected_states.update({d.ifc_definition_id: d.is_selected for d in props.drawings if d.is_drawing}) props.drawings.clear() drawings = [e for e in tool.Ifc.get().by_type("IfcAnnotation") if e.ObjectType == "DRAWING"]