diff --git a/src/bonsai/bonsai/bim/module/drawing/data.py b/src/bonsai/bonsai/bim/module/drawing/data.py index cfe1492247..65633748ca 100644 --- a/src/bonsai/bonsai/bim/module/drawing/data.py +++ b/src/bonsai/bonsai/bim/module/drawing/data.py @@ -285,7 +285,7 @@ class DecoratorData: return thickness @classmethod - def get_section_markers_display_data(cls, obj): + def get_section_markers_display_data(cls, obj: bpy.types.Object) -> Union[dict[str, Any], None]: """used by IfcAnnotations with ObjectType = "SECTION" """ result = cls.data.get(obj.name, None) if result is not None: @@ -327,10 +327,11 @@ class DecoratorData: return display_data @classmethod - def get_text_data(cls, obj: bpy.types.Object) -> dict: + def get_text_data(cls, obj: bpy.types.Object) -> dict[str, Any]: """used by Ifc Annotations with ObjectType = "TEXT" / "TEXT_LEADER"\n returns font size in mm for current ifc text object""" element = tool.Ifc.get_entity(obj) + assert element props = tool.Drawing.get_text_props(obj) # getting font size pset_data = ifcopenshell.util.element.get_pset(element, "EPset_Annotation") or {} @@ -371,16 +372,18 @@ class DecoratorData: return {"Literals": literals_data, "FontSize": font_size, "Symbol": symbol, "Newline_At": newline_at} @classmethod - def get_dimension_data(cls, obj): + def get_dimension_data(cls, obj: bpy.types.Object) -> dict[str, Any]: """used by Ifc Annotations with ObjectType: DIMENSION / DIAMETER / SECTION_LEVEL / PLAN_LEVEL / RADIUS """ element = tool.Ifc.get_entity(obj) + assert element dimension_style = "arrow" fill_bg = False classes = ifcopenshell.util.element.get_pset(element, "EPset_Annotation", "Classes") if classes: + assert type(classes) is str classes_split = classes.lower().split() if "oblique" in classes_split: dimension_style = "oblique" @@ -406,15 +409,17 @@ class DecoratorData: } @classmethod - def get_fall_data(cls, obj): + def get_fall_data(cls, obj: bpy.types.Object) -> dict[str, Union[str, None]]: object_type = None if element := tool.Ifc.get_entity(obj): object_type = ifcopenshell.util.element.get_predefined_type(element) return {"object_type": object_type} @classmethod - def get_symbol_data(cls, obj): - return tool.Drawing.get_annotation_symbol(tool.Ifc.get_entity(obj)) + def get_symbol_data(cls, obj: bpy.types.Object) -> Union[str, None]: + element = tool.Ifc.get_entity(obj) + assert element + return tool.Drawing.get_annotation_symbol(element) @classmethod def object_decorators(cls, handler): diff --git a/src/bonsai/bonsai/bim/module/model/ui.py b/src/bonsai/bonsai/bim/module/model/ui.py index f8eb50a38e..000a9a46f4 100644 --- a/src/bonsai/bonsai/bim/module/model/ui.py +++ b/src/bonsai/bonsai/bim/module/model/ui.py @@ -36,6 +36,7 @@ from bonsai.bim.module.model.stair import regenerate_stair_mesh from bonsai.bim.module.model.railing import update_railing_modifier_bmesh from bonsai.bim.module.model.roof import update_roof_modifier_bmesh from collections.abc import Iterable +from typing import Any class BIM_MT_type_manager_menu(bpy.types.Menu): @@ -95,6 +96,7 @@ class LaunchTypeManager(bpy.types.Operator): return context.window_manager.invoke_props_dialog(self, width=550, title="Type Manager", confirm_text="Close") def draw(self, context): + assert self.layout props = tool.Model.get_model_props() row = self.layout.row(align=True) text = f"{AuthoringData.data['total_types']} {AuthoringData.data['ifc_element_type'] or 'Types'}" @@ -135,6 +137,7 @@ class LaunchTypeManager(bpy.types.Operator): flow = self.layout.grid_flow(row_major=True, columns=3, even_columns=True, even_rows=True, align=True) + relating_type: dict[str, Any] for relating_type in AuthoringData.data["paginated_relating_types"]: outer_col = flow.column() box = outer_col.box() diff --git a/src/bonsai/bonsai/bim/module/model/workspace.py b/src/bonsai/bonsai/bim/module/model/workspace.py index 90a9849e30..618d0db95b 100644 --- a/src/bonsai/bonsai/bim/module/model/workspace.py +++ b/src/bonsai/bonsai/bim/module/model/workspace.py @@ -29,7 +29,7 @@ from bpy.types import WorkSpaceTool, Menu from bonsai.bim.module.model.data import AuthoringData, ItemData from bonsai.bim.module.system.data import PortData from bonsai.bim.module.model.prop import get_ifc_class -from typing import Optional, Union +from typing import Optional, Union, Any from functools import partial @@ -506,15 +506,17 @@ class CreateObjectUI: cls.draw_type_manager_launcher(context) @classmethod - def draw_container_info(cls, context): + def draw_container_info(cls, context: bpy.types.Context) -> None: text = AuthoringData.data["default_container"] + assert context.region if context.region.type == "UI": text = f"Container: {text}" cls.layout.row(align=True).label(text=text, icon="OUTLINER_COLLECTION") @classmethod - def draw_type_manager_launcher(cls, context): + def draw_type_manager_launcher(cls, context: bpy.types.Context) -> None: + assert context.region ui_context = context.region.type props = tool.Model.get_model_props() row = cls.layout.row(align=True) @@ -568,7 +570,8 @@ class CreateObjectUI: op.ifc_element_type = AuthoringData.data["ifc_element_type"] @classmethod - def draw_add_object(cls, context): + def draw_add_object(cls, context: bpy.types.Context) -> None: + assert context.region ui_context = str(context.region.type) row = cls.layout.row(align=True) if AuthoringData.data["relating_type_id"]: @@ -580,7 +583,8 @@ class CreateObjectUI: row.label(text="No Construction Type", icon="FILE_3D") @classmethod - def draw_add_object_parameters(cls, context): + def draw_add_object_parameters(cls, context: bpy.types.Context) -> None: + assert context.region ui_context = str(context.region.type) row = cls.layout.row(align=True) if not AuthoringData.data["relating_type_id"]: @@ -633,7 +637,8 @@ class CreateObjectUI: row.prop(data=cls.props, property="rl_mode", text="RL Mode" if ui_context != "TOOL_HEADER" else "RL") @classmethod - def draw_thumbnail(cls, context): + def draw_thumbnail(cls, context: bpy.types.Context) -> None: + assert context.region ui_context = context.region.type row = cls.layout.row(align=True) if not AuthoringData.data["ifc_element_type"]: diff --git a/src/bonsai/bonsai/bim/module/unit/prop.py b/src/bonsai/bonsai/bim/module/unit/prop.py index f0f04e16ae..a335532294 100644 --- a/src/bonsai/bonsai/bim/module/unit/prop.py +++ b/src/bonsai/bonsai/bim/module/unit/prop.py @@ -52,7 +52,6 @@ def get_named_unit_types(self: "BIMUnitProperties", context: bpy.types.Context) class Unit(PropertyGroup): - name: StringProperty(name="Name") unit_type: StringProperty(name="Unit Type") is_assigned: BoolProperty(name="Is Assigned") ifc_class: StringProperty(name="IFC Class") diff --git a/src/bonsai/bonsai/bim/module/unit/ui.py b/src/bonsai/bonsai/bim/module/unit/ui.py index f7b55a96e3..27f4f78a7e 100644 --- a/src/bonsai/bonsai/bim/module/unit/ui.py +++ b/src/bonsai/bonsai/bim/module/unit/ui.py @@ -16,11 +16,17 @@ # You should have received a copy of the GNU General Public License # along with Bonsai. If not, see . +from __future__ import annotations import bonsai.bim.helper import bonsai.tool as tool +import bpy from bpy.types import Panel, UIList from bonsai.bim.helper import prop_with_search from bonsai.bim.module.unit.data import UnitsData +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from bonsai.bim.module.unit.prop import BIMUnitProperties, Unit class BIM_PT_units(Panel): @@ -102,7 +108,16 @@ class BIM_PT_units(Panel): class BIM_UL_units(UIList): - def draw_item(self, context, layout, data, item, icon, active_data, active_propname): + def draw_item( + self, + context, + layout: bpy.types.UILayout, + data: BIMUnitProperties, + item: Unit, + icon_: int, + active_data, + active_propname, + ) -> None: props = tool.Unit.get_unit_props() if item: icon = "MOD_MESHDEFORM" diff --git a/src/bonsai/bonsai/core/unit.py b/src/bonsai/bonsai/core/unit.py index e9f002b95c..a075c9c5e5 100644 --- a/src/bonsai/bonsai/core/unit.py +++ b/src/bonsai/bonsai/core/unit.py @@ -26,7 +26,7 @@ if TYPE_CHECKING: import bonsai.tool as tool -def assign_scene_units(ifc: tool.Ifc, unit: tool.Unit) -> None: +def assign_scene_units(ifc: type[tool.Ifc], unit: type[tool.Unit]) -> None: if unit.is_scene_unit_metric(): prefix = unit.get_scene_unit_si_prefix("LENGTHUNIT") lengthunit = ifc.run("unit.add_si_unit", unit_type="LENGTHUNIT", prefix=prefix) @@ -44,66 +44,66 @@ def assign_scene_units(ifc: tool.Ifc, unit: tool.Unit) -> None: ifc.run("unit.assign_unit", units=[lengthunit, areaunit, volumeunit, planeangleunit]) -def assign_unit(ifc: tool.Ifc, unit_tool: tool.Unit, unit: ifcopenshell.entity_instance) -> None: +def assign_unit(ifc: type[tool.Ifc], unit_tool: type[tool.Unit], unit: ifcopenshell.entity_instance) -> None: ifc.run("unit.assign_unit", units=[unit]) unit_tool.import_units() -def unassign_unit(ifc: tool.Ifc, unit_tool: tool.Unit, unit: ifcopenshell.entity_instance) -> None: +def unassign_unit(ifc: type[tool.Ifc], unit_tool: type[tool.Unit], unit: ifcopenshell.entity_instance) -> None: ifc.run("unit.unassign_unit", units=[unit]) unit_tool.import_units() -def load_units(unit: tool.Unit) -> None: +def load_units(unit: type[tool.Unit]) -> None: unit.import_units() unit.enable_editing_units() -def disable_unit_editing_ui(unit: tool.Unit) -> None: +def disable_unit_editing_ui(unit: type[tool.Unit]) -> None: unit.disable_editing_units() -def remove_unit(ifc: tool.Ifc, unit_tool: tool.Unit, unit: ifcopenshell.entity_instance) -> None: +def remove_unit(ifc: type[tool.Ifc], unit_tool: type[tool.Unit], unit: ifcopenshell.entity_instance) -> None: ifc.run("unit.remove_unit", unit=unit) unit_tool.import_units() -def add_monetary_unit(ifc: tool.Ifc, unit: tool.Unit) -> ifcopenshell.entity_instance: +def add_monetary_unit(ifc: type[tool.Ifc], unit: type[tool.Unit]) -> ifcopenshell.entity_instance: result = ifc.run("unit.add_monetary_unit") unit.import_units() return result -def add_si_unit(ifc: tool.Ifc, unit: tool.Unit, unit_type: str) -> ifcopenshell.entity_instance: +def add_si_unit(ifc: type[tool.Ifc], unit: type[tool.Unit], unit_type: str) -> ifcopenshell.entity_instance: result = ifc.run("unit.add_si_unit", unit_type=unit_type) unit.import_units() return result def add_context_dependent_unit( - ifc: tool.Ifc, unit: tool.Unit, unit_type: str, name: str + ifc: type[tool.Ifc], unit: type[tool.Unit], unit_type: str, name: str ) -> ifcopenshell.entity_instance: result = ifc.run("unit.add_context_dependent_unit", unit_type=unit_type, name=name) unit.import_units() return result -def add_conversion_based_unit(ifc: tool.Ifc, unit: tool.Unit, name: str) -> ifcopenshell.entity_instance: +def add_conversion_based_unit(ifc: type[tool.Ifc], unit: type[tool.Unit], name: str) -> ifcopenshell.entity_instance: result = ifc.run("unit.add_conversion_based_unit", name=name) unit.import_units() return result -def enable_editing_unit(unit_tool: tool.Unit, unit: ifcopenshell.entity_instance) -> None: +def enable_editing_unit(unit_tool: type[tool.Unit], unit: ifcopenshell.entity_instance) -> None: unit_tool.set_active_unit(unit) unit_tool.import_unit_attributes(unit) -def disable_editing_unit(unit: tool.Unit) -> None: +def disable_editing_unit(unit: type[tool.Unit]) -> None: unit.clear_active_unit() -def edit_unit(ifc: tool.Ifc, unit_tool: tool.Unit, unit: ifcopenshell.entity_instance) -> None: +def edit_unit(ifc: type[tool.Ifc], unit_tool: type[tool.Unit], unit: ifcopenshell.entity_instance) -> None: attributes = unit_tool.export_unit_attributes() if unit_tool.is_unit_class(unit, "IfcMonetaryUnit"): ifc.run("unit.edit_monetary_unit", unit=unit, attributes=attributes) diff --git a/src/bonsai/bonsai/tool/unit.py b/src/bonsai/bonsai/tool/unit.py index f296a29500..be5bc0fe5a 100644 --- a/src/bonsai/bonsai/tool/unit.py +++ b/src/bonsai/bonsai/tool/unit.py @@ -125,7 +125,7 @@ class Unit(bonsai.core.tool.Unit): props = tool.Unit.get_unit_props() props.units.clear() - units = [] + units: list[ifcopenshell.entity_instance] = [] for unit_class in ["IfcDerivedUnit", "IfcMonetaryUnit", "IfcNamedUnit"]: units += tool.Ifc.get().by_type(unit_class) diff --git a/src/ifcopenshell-python/ifcopenshell/util/unit.py b/src/ifcopenshell-python/ifcopenshell/util/unit.py index b7e91c798b..6e78d73546 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/unit.py +++ b/src/ifcopenshell-python/ifcopenshell/util/unit.py @@ -695,6 +695,7 @@ def calculate_unit_scale(ifc_file: ifcopenshell.file, unit_type: str = "LENGTHUN if not (projects := ifc_file.by_type("IfcProject")) or not (units := projects[0].UnitsInContext): return 1 unit_scale = 1 + unit: ifcopenshell.entity_instance for unit in units.Units: if not hasattr(unit, "UnitType") or unit.UnitType != unit_type: continue