From cd8f6e2c78a548abf9f5e730fd4a0f5c190d793d Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Mon, 14 Oct 2024 14:31:26 +0500 Subject: [PATCH] typing --- src/bonsai/bonsai/bim/helper.py | 2 +- src/bonsai/bonsai/bim/module/model/wall.py | 6 +-- .../bonsai/bim/module/project/operator.py | 20 ++++++---- src/bonsai/bonsai/core/document.py | 37 +++++++++++++------ src/bonsai/bonsai/tool/document.py | 33 +++++++++-------- src/bonsai/bonsai/tool/geometry.py | 2 +- 6 files changed, 60 insertions(+), 40 deletions(-) diff --git a/src/bonsai/bonsai/bim/helper.py b/src/bonsai/bonsai/bim/helper.py index c7d4bbacc6..37443df6a0 100644 --- a/src/bonsai/bonsai/bim/helper.py +++ b/src/bonsai/bonsai/bim/helper.py @@ -40,7 +40,7 @@ if TYPE_CHECKING: # - None - property should be imported by default workflow # - True - setting value for imported attribute should be skipped # - False - property should be skipped entirely from import - ImportCallback = Callable[[str, Optional[bonsai.bim.prop.Attribute], dict[str, Any], Union[bool, None]]] + ImportCallback = Callable[[str, Optional[bonsai.bim.prop.Attribute], dict[str, Any]], Union[bool, None]] # ExportCallback return values: # - True - property should be skipped entirely from export # - False - property should be exproted by default workflow diff --git a/src/bonsai/bonsai/bim/module/model/wall.py b/src/bonsai/bonsai/bim/module/model/wall.py index 70c198dea3..b98480e14c 100644 --- a/src/bonsai/bonsai/bim/module/model/wall.py +++ b/src/bonsai/bonsai/bim/module/model/wall.py @@ -464,8 +464,8 @@ class DumbWallAligner: class DumbWallRecalculator: - def recalculate(self, walls): - queue = set() + def recalculate(self, walls: list[bpy.types.Object]) -> None: + queue: set[tuple[ifcopenshell.entity_instance, bpy.types.Object]] = set() for wall in walls: element = tool.Ifc.get_entity(wall) queue.add((element, wall)) @@ -1144,7 +1144,7 @@ class DumbWallJoiner: self.recreate_wall(element1, wall1, axis1["reference"], axis1["reference"]) self.recreate_wall(element2, wall2, axis2["reference"], axis2["reference"]) - def recreate_wall(self, element, obj, axis=None, body=None): + def recreate_wall(self, element: ifcopenshell.entity_instance, obj: bpy.types.Object, axis=None, body=None) -> None: if axis is None or body is None: axis = body = tool.Model.get_wall_axis(obj)["reference"] self.axis = copy.deepcopy(axis) diff --git a/src/bonsai/bonsai/bim/module/project/operator.py b/src/bonsai/bonsai/bim/module/project/operator.py index beae6e990b..a08a67d0d8 100644 --- a/src/bonsai/bonsai/bim/module/project/operator.py +++ b/src/bonsai/bonsai/bim/module/project/operator.py @@ -29,6 +29,8 @@ import numpy as np import ifcopenshell import ifcopenshell.api import ifcopenshell.api.project +import ifcopenshell.geom +import ifcopenshell.ifcopenshell_wrapper as W import ifcopenshell.util.file import ifcopenshell.util.selector import ifcopenshell.util.geolocation @@ -1412,10 +1414,14 @@ class LoadLinkedProject(bpy.types.Operator): bl_options = {"REGISTER", "UNDO"} filepath: bpy.props.StringProperty() + file: ifcopenshell.file + meshes: dict[str, bpy.types.Mesh] + # Material names is derived from diffuse as in 'r-g-b-a'. + blender_mats: dict[str, bpy.types.Material] + def execute(self, context): import ifcpatch import multiprocessing - import ifcopenshell.geom start = time.time() @@ -1528,7 +1534,7 @@ class LoadLinkedProject(bpy.types.Operator): mats, mapping = np.unique(mats, axis=0, return_inverse=True) midx = mapping[midx] - mat_results = [] + mat_results: list[bpy.types.Material] = [] for mat in mats: mat = tuple(mat) blender_mat = blender_mats.get(mat, None) @@ -1660,10 +1666,10 @@ class LoadLinkedProject(bpy.types.Operator): def process_occurrence(self, shape: ShapeElementType) -> None: element = self.file.by_id(shape.id) - faces = shape.geometry.faces - verts = shape.geometry.verts - materials = shape.geometry.materials - material_ids = shape.geometry.material_ids + faces: tuple[int, ...] = shape.geometry.faces + verts: tuple[float, ...] = shape.geometry.verts + materials: tuple[W.style, ...] = shape.geometry.materials + material_ids: tuple[int, ...] = shape.geometry.material_ids mat = ifcopenshell.util.shape.get_shape_matrix(shape) @@ -1747,7 +1753,7 @@ class LoadLinkedProject(bpy.types.Operator): self.collection.objects.link(obj) - def create_object(self, verts, faces, materials, material_ids, guids, guid_ids): + def create_object(self, verts, faces, materials: list[bpy.types.Material], material_ids, guids, guid_ids): num_vertices = len(verts) // 3 if not num_vertices: return diff --git a/src/bonsai/bonsai/core/document.py b/src/bonsai/bonsai/core/document.py index 222892a287..e82360dbb9 100644 --- a/src/bonsai/bonsai/core/document.py +++ b/src/bonsai/bonsai/core/document.py @@ -16,15 +16,23 @@ # You should have received a copy of the GNU General Public License # along with Bonsai. If not, see . +from __future__ import annotations +from typing import TYPE_CHECKING, Optional -def load_project_documents(document): +if TYPE_CHECKING: + import bpy + import ifcopenshell + import bonsai.tool as tool + + +def load_project_documents(document: tool.Document) -> None: document.clear_document_tree() document.import_project_documents() document.clear_breadcrumbs() document.enable_editing_ui() -def load_document(document_tool, document=None): +def load_document(document_tool: tool.Document, document: ifcopenshell.entity_instance) -> None: document_tool.clear_document_tree() document_tool.import_subdocuments(document) document_tool.import_references(document) @@ -32,7 +40,7 @@ def load_document(document_tool, document=None): document_tool.add_breadcrumb(document) -def load_parent_document(document): +def load_parent_document(document: tool.Document) -> None: document.clear_document_tree() document.remove_latest_breadcrumb() parent = document.get_active_breadcrumb() @@ -44,21 +52,21 @@ def load_parent_document(document): document.import_project_documents() -def disable_document_editing_ui(document): +def disable_document_editing_ui(document: tool.Document) -> None: document.disable_editing_ui() document.disable_editing_document() -def enable_editing_document(document_tool, document=None): +def enable_editing_document(document_tool: tool.Document, document: ifcopenshell.entity_instance) -> None: document_tool.import_document_attributes(document) document_tool.set_active_document(document) -def disable_editing_document(document): +def disable_editing_document(document: tool.Document) -> None: document.disable_editing_document() -def add_information(ifc, document): +def add_information(ifc: tool.Ifc, document: tool.Document) -> None: document.clear_document_tree() parent = document.get_active_breadcrumb() information = ifc.run("document.add_information", parent=parent) @@ -70,15 +78,16 @@ def add_information(ifc, document): document.import_project_documents() -def add_reference(ifc, document): +def add_reference(ifc: tool.Ifc, document: tool.Document) -> None: parent = document.get_active_breadcrumb() + assert parent ifc.run("document.add_reference", information=parent) document.clear_document_tree() document.import_subdocuments(parent) document.import_references(parent) -def edit_document(ifc, document_tool, document=None): +def edit_document(ifc: tool.Ifc, document_tool: tool.Document, document: ifcopenshell.entity_instance) -> None: attributes = document_tool.export_document_attributes() if document_tool.is_document_information(document): ifc.run("document.edit_information", information=document, attributes=attributes) @@ -94,7 +103,7 @@ def edit_document(ifc, document_tool, document=None): document_tool.import_project_documents() -def remove_document(ifc, document_tool, document=None): +def remove_document(ifc: tool.Ifc, document_tool: tool.Document, document: ifcopenshell.entity_instance) -> None: document_tool.clear_document_tree() if document_tool.is_document_information(document): ifc.run("document.remove_information", information=document) @@ -108,9 +117,13 @@ def remove_document(ifc, document_tool, document=None): document_tool.import_project_documents() -def assign_document(ifc, product=None, document=None): +def assign_document( + ifc: tool.Ifc, product: ifcopenshell.entity_instance, document: ifcopenshell.entity_instance +) -> None: ifc.run("document.assign_document", products=[product], document=document) -def unassign_document(ifc, product=None, document=None): +def unassign_document( + ifc: tool.Ifc, product: ifcopenshell.entity_instance, document: ifcopenshell.entity_instance +) -> None: ifc.run("document.unassign_document", products=[product], document=document) diff --git a/src/bonsai/bonsai/tool/document.py b/src/bonsai/bonsai/tool/document.py index 62ec525f10..4887e55e14 100644 --- a/src/bonsai/bonsai/tool/document.py +++ b/src/bonsai/bonsai/tool/document.py @@ -18,58 +18,59 @@ import bpy import ifcopenshell.util.system +import bonsai.bim.helper import bonsai.core.tool import bonsai.tool as tool -from bonsai.bim import import_ifc +from typing import Any, Union class Document(bonsai.core.tool.Document): @classmethod - def add_breadcrumb(cls, document): + def add_breadcrumb(cls, document: ifcopenshell.entity_instance) -> None: props = bpy.context.scene.BIMDocumentProperties new = props.breadcrumbs.add() new.name = str(document.id()) @classmethod - def clear_breadcrumbs(cls): + def clear_breadcrumbs(cls) -> None: props = bpy.context.scene.BIMDocumentProperties props.breadcrumbs.clear() @classmethod - def clear_document_tree(cls): + def clear_document_tree(cls) -> None: props = bpy.context.scene.BIMDocumentProperties props.documents.clear() @classmethod - def disable_editing_document(cls): + def disable_editing_document(cls) -> None: bpy.context.scene.BIMDocumentProperties.active_document_id = 0 @classmethod - def disable_editing_ui(cls): + def disable_editing_ui(cls) -> None: bpy.context.scene.BIMDocumentProperties.is_editing = False @classmethod - def enable_editing_ui(cls): + def enable_editing_ui(cls) -> None: bpy.context.scene.BIMDocumentProperties.is_editing = True @classmethod - def export_document_attributes(cls): + def export_document_attributes(cls) -> dict[str, Any]: return bonsai.bim.helper.export_attributes(bpy.context.scene.BIMDocumentProperties.document_attributes) @classmethod - def get_active_breadcrumb(cls): + def get_active_breadcrumb(cls) -> Union[ifcopenshell.entity_instance, None]: props = bpy.context.scene.BIMDocumentProperties if len(props.breadcrumbs): return tool.Ifc.get().by_id(int(props.breadcrumbs[-1].name)) @classmethod - def import_document_attributes(cls, document): + def import_document_attributes(cls, document: ifcopenshell.entity_instance) -> None: props = bpy.context.scene.BIMDocumentProperties props.document_attributes.clear() bonsai.bim.helper.import_attributes2(document, props.document_attributes) @classmethod - def import_project_documents(cls): + def import_project_documents(cls) -> None: props = bpy.context.scene.BIMDocumentProperties props.documents.clear() project = tool.Ifc.get().by_type("IfcProject")[0] @@ -86,7 +87,7 @@ class Document(bonsai.core.tool.Document): new.identification = element.Identification or "*" @classmethod - def import_references(cls, document): + def import_references(cls, document: ifcopenshell.entity_instance) -> None: props = bpy.context.scene.BIMDocumentProperties if tool.Ifc.get_schema() == "IFC2X3": for element in document.DocumentReferences or []: @@ -106,7 +107,7 @@ class Document(bonsai.core.tool.Document): new.is_information = False @classmethod - def import_subdocuments(cls, document): + def import_subdocuments(cls, document: ifcopenshell.entity_instance) -> None: props = bpy.context.scene.BIMDocumentProperties if document.IsPointer: for element in document.IsPointer[0].RelatedDocuments or []: @@ -120,15 +121,15 @@ class Document(bonsai.core.tool.Document): new.identification = element.Identification or "*" @classmethod - def is_document_information(cls, document): + def is_document_information(cls, document: ifcopenshell.entity_instance) -> bool: return document.is_a("IfcDocumentInformation") @classmethod - def remove_latest_breadcrumb(cls): + def remove_latest_breadcrumb(cls) -> None: props = bpy.context.scene.BIMDocumentProperties if len(props.breadcrumbs): props.breadcrumbs.remove(len(props.breadcrumbs) - 1) @classmethod - def set_active_document(cls, document): + def set_active_document(cls, document: ifcopenshell.entity_instance) -> None: bpy.context.scene.BIMDocumentProperties.active_document_id = document.id() diff --git a/src/bonsai/bonsai/tool/geometry.py b/src/bonsai/bonsai/tool/geometry.py index 6d5b4244d2..21e999c52e 100644 --- a/src/bonsai/bonsai/tool/geometry.py +++ b/src/bonsai/bonsai/tool/geometry.py @@ -645,7 +645,7 @@ class Geometry(bonsai.core.tool.Geometry): @classmethod def reimport_element_representations( cls, obj: bpy.types.Object, representation: ifcopenshell.entity_instance, apply_openings: bool = True - ) -> Union[bpy.types.Mesh, bpy.types.Curve]: + ) -> None: element = tool.Ifc.get_entity(obj) assert element