From aa5f08880ba58a2ed738d6ec52f04bf772b3029b Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Fri, 16 May 2025 18:48:50 +0500 Subject: [PATCH] typing --- .../bonsai/bim/module/drawing/decoration.py | 2 +- .../bonsai/bim/module/drawing/operator.py | 25 ++++++++++++++++--- src/bonsai/bonsai/bim/module/drawing/prop.py | 1 + .../bonsai/bim/module/geometry/operator.py | 9 ++++--- src/bonsai/bonsai/core/misc.py | 2 +- src/bonsai/bonsai/core/root.py | 12 ++++++--- 6 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/drawing/decoration.py b/src/bonsai/bonsai/bim/module/drawing/decoration.py index 83c2b8560b..61987a7436 100644 --- a/src/bonsai/bonsai/bim/module/drawing/decoration.py +++ b/src/bonsai/bonsai/bim/module/drawing/decoration.py @@ -1650,7 +1650,7 @@ class CutDecorator: all_vertex_i_offset = 0 selected_vertex_i_offset = 0 - classes_no_cut_str = bpy.context.scene.DocProperties.classes_no_cut + classes_no_cut_str = tool.Drawing.get_document_props().classes_no_cut classes_no_cut = [word.strip() for word in classes_no_cut_str.split(",")] for obj in [o for o in bpy.context.visible_objects if o.type == "MESH"]: diff --git a/src/bonsai/bonsai/bim/module/drawing/operator.py b/src/bonsai/bonsai/bim/module/drawing/operator.py index a0a0f07138..d773fc55d6 100644 --- a/src/bonsai/bonsai/bim/module/drawing/operator.py +++ b/src/bonsai/bonsai/bim/module/drawing/operator.py @@ -225,14 +225,27 @@ class CreateDrawing(bpy.types.Operator): + "Add the CTRL modifier to optionally open drawings to view them as\n" + "they are created" ) - print_all: bpy.props.BoolProperty(name="Print All", default=False, options={"SKIP_SAVE"}) - open_viewer: bpy.props.BoolProperty(name="Open in Viewer", default=False, options={"SKIP_SAVE"}) - sync: bpy.props.BoolProperty( + print_all: bpy.props.BoolProperty( # pyright: ignore[reportRedeclaration] + name="Print All", + default=False, + options={"SKIP_SAVE"}, + ) + open_viewer: bpy.props.BoolProperty( # pyright: ignore[reportRedeclaration] + name="Open in Viewer", + default=False, + options={"SKIP_SAVE"}, + ) + sync: bpy.props.BoolProperty( # pyright: ignore[reportRedeclaration] name="Sync Before Creating Drawing", description="Could save some time if you're sure IFC and current Blender session are already in sync", default=True, ) + if TYPE_CHECKING: + print_all: bool + open_viewer: bool + sync: bool + drawing_name: str is_manifold_cache: dict[str, bool] @@ -268,6 +281,7 @@ class CreateDrawing(bpy.types.Operator): assert context.scene and context.scene.camera active_drawing_id = tool.Blender.get_ifc_definition_id(context.scene.camera) + original_drawing_id = None if self.print_all: original_drawing_id = active_drawing_id drawings_to_print = [d.ifc_definition_id for d in self.props.drawings if d.is_selected and d.is_drawing] @@ -338,6 +352,7 @@ class CreateDrawing(bpy.types.Operator): if not self.open_viewer: self.report({"INFO"}, f"{len(drawings_to_print)} drawings created...") if self.print_all: + assert original_drawing_id is not None bpy.ops.bim.activate_drawing(drawing=original_drawing_id, should_view_from_camera=False) return {"FINISHED"} @@ -2150,6 +2165,7 @@ class ActivateDrawingBase(tool.Ifc.Operator): return self.execute(context) def _execute(self, context) -> set["rna_enums.OperatorReturnItems"]: + assert context.scene props = tool.Drawing.get_document_props() if props.is_editing_drawings == False: bpy.ops.bim.load_drawings() @@ -2161,12 +2177,14 @@ class ActivateDrawingBase(tool.Ifc.Operator): tool.Blender.activate_camera(tool.Drawing.import_temporary_drawing_camera(drawing)) return {"FINISHED"} + viewport_position = None if not self.should_view_from_camera: viewport_position = tool.Blender.get_viewport_position() core.activate_drawing_view(tool.Ifc, tool.Blender, tool.Drawing, drawing=drawing) if not self.should_view_from_camera: + assert viewport_position tool.Blender.set_viewport_position(viewport_position) dprops.active_drawing_id = self.drawing @@ -2182,6 +2200,7 @@ class ActivateDrawingBase(tool.Ifc.Operator): # Save drawing bounds to the .ifc file camera = context.scene.camera + assert camera camera_props = tool.Drawing.get_camera_props(camera) if camera_props.update_representation(camera.matrix_world): bpy.ops.bim.update_representation(obj=camera.name, ifc_representation_class="") diff --git a/src/bonsai/bonsai/bim/module/drawing/prop.py b/src/bonsai/bonsai/bim/module/drawing/prop.py index b3da33f456..3d3a43f8fd 100644 --- a/src/bonsai/bonsai/bim/module/drawing/prop.py +++ b/src/bonsai/bonsai/bim/module/drawing/prop.py @@ -496,6 +496,7 @@ class DocProperties(PropertyGroup): imperial_precision: str tolerance: float classes_to_wireframe: str + classes_no_cut: str def get_active_drawing(self) -> Union[ifcopenshell.entity_instance, None]: drawing_id = self.active_drawing_id diff --git a/src/bonsai/bonsai/bim/module/geometry/operator.py b/src/bonsai/bonsai/bim/module/geometry/operator.py index d7ccb68cda..7042789adb 100644 --- a/src/bonsai/bonsai/bim/module/geometry/operator.py +++ b/src/bonsai/bonsai/bim/module/geometry/operator.py @@ -22,7 +22,9 @@ import bmesh import numpy as np import numpy.typing as npt import ifcopenshell +import ifcopenshell.api.geometry import ifcopenshell.api.layer +import ifcopenshell.api.material import ifcopenshell.api.root import ifcopenshell.api.style import ifcopenshell.util.element @@ -583,9 +585,9 @@ class UpdateRepresentation(bpy.types.Operator, tool.Ifc.Operator): # We are explicitly casting to a tessellation, so remove all parametric materials. element_type = ifcopenshell.util.element.get_type(product) if element_type: # Some invalid IFCs use material sets without a type. - ifcopenshell.api.run("material.unassign_material", tool.Ifc.get(), products=[element_type]) + ifcopenshell.api.material.unassign_material(self.file, products=[element_type]) tool.Material.ensure_material_unassigned([element_type]) - ifcopenshell.api.run("material.unassign_material", tool.Ifc.get(), products=[product]) + ifcopenshell.api.material.unassign_material(self.file, products=[product]) tool.Material.ensure_material_unassigned([product]) else: # These objects are parametrically based on an axis and should not be modified as a mesh @@ -603,6 +605,7 @@ class UpdateRepresentation(bpy.types.Operator, tool.Ifc.Operator): # added this as a fallback for easier transition some annotation types to 3d # if they were create before as 2d element = tool.Ifc.get_entity(obj) + assert element if tool.Drawing.is_annotation_object_type(element, ("FALL", "SECTION_LEVEL", "PLAN_LEVEL")): context_of_items = tool.Drawing.get_annotation_context("MODEL_VIEW") @@ -626,7 +629,7 @@ class UpdateRepresentation(bpy.types.Operator, tool.Ifc.Operator): representation_data["text_literal"] = tool.Geometry.get_text_literal(old_representation) # TODO: replace with core.add_representation? - new_representation = ifcopenshell.api.run("geometry.add_representation", self.file, **representation_data) + new_representation = ifcopenshell.api.geometry.add_representation(self.file, **representation_data) if new_representation is None: self.report({"ERROR"}, "Error creating representation for Blender object.") return {"CANCELLED"} diff --git a/src/bonsai/bonsai/core/misc.py b/src/bonsai/bonsai/core/misc.py index 761cd52afc..a69ffb2180 100644 --- a/src/bonsai/bonsai/core/misc.py +++ b/src/bonsai/bonsai/core/misc.py @@ -25,7 +25,7 @@ if TYPE_CHECKING: import bonsai.tool as tool -def resize_to_storey(misc: tool.Misc, ifc: tool.Ifc, obj: bpy.types.Object, total_storeys: int) -> None: +def resize_to_storey(misc: type[tool.Misc], ifc: type[tool.Ifc], obj: bpy.types.Object, total_storeys: int) -> None: storey = misc.get_object_storey(obj) if not storey: return diff --git a/src/bonsai/bonsai/core/root.py b/src/bonsai/bonsai/core/root.py index 347b0fea4d..d1b88307d2 100644 --- a/src/bonsai/bonsai/core/root.py +++ b/src/bonsai/bonsai/core/root.py @@ -26,7 +26,11 @@ if TYPE_CHECKING: def copy_class( - ifc: tool.Ifc, collector: tool.Collector, geometry: tool.Geometry, root: tool.Root, obj: bpy.types.Object + ifc: type[tool.Ifc], + collector: type[tool.Collector], + geometry: type[tool.Geometry], + root: type[tool.Root], + obj: bpy.types.Object, ) -> ifcopenshell.entity_instance | None: element = ifc.get_entity(obj) if not element: @@ -55,9 +59,9 @@ def copy_class( def assign_class( - ifc: tool.Ifc, - collector: tool.Collector, - root: tool.Root, + ifc: type[tool.Ifc], + collector: type[tool.Collector], + root: type[tool.Root], obj: bpy.types.Object, ifc_class: str, context: Optional[ifcopenshell.entity_instance] = None,