From d8a250f153e7ccee6ac450e413c7b36f36f741e8 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Mon, 10 Feb 2025 14:16:59 +0500 Subject: [PATCH] Update Annotation Tool types when selecting elements #6134 Similar to other BIM Tools Update handler.py --- src/bonsai/bonsai/bim/handler.py | 20 ++++++++++++++++--- .../bonsai/bim/module/model/workspace.py | 2 -- src/bonsai/bonsai/tool/blender.py | 17 ++++++++++++++++ src/bonsai/bonsai/tool/drawing.py | 15 +++++++++----- 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/bonsai/bonsai/bim/handler.py b/src/bonsai/bonsai/bim/handler.py index 16a2cdc636..84cee64dab 100644 --- a/src/bonsai/bonsai/bim/handler.py +++ b/src/bonsai/bonsai/bim/handler.py @@ -29,7 +29,6 @@ from bpy.app.handlers import persistent from bonsai.bim.ifc import IfcStore from bonsai.bim.module.owner.prop import get_user_person, get_user_organisation from bonsai.bim.module.model.data import AuthoringData -from bonsai.bim.module.model.workspace import LIST_OF_TOOLS, TOOLS_TO_CLASSES_MAP from bonsai.bim.module.aggregate.decorator import AggregateDecorator from bonsai.bim.module.georeference.decorator import GeoreferenceDecorator from bonsai.bim.module.model.decorator import WallAxisDecorator, SlabDirectionDecorator @@ -108,24 +107,39 @@ def update_bim_tool_props(): return mode = bpy.context.mode current_tool = bpy.context.workspace.tools.from_space_view3d_mode(mode) - if not current_tool or current_tool.idname not in LIST_OF_TOOLS: + if not current_tool or current_tool.idname not in tool.Blender.get_list_of_tools(): return element = tool.Ifc.get_entity(obj) if not element: return + representation = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW") if not representation: return props = tool.Model.get_model_props() - if element.is_a("IfcElementType") or element.is_a("IfcElement"): + aprops = tool.Drawing.get_annotation_props() + TOOLS_TO_CLASSES_MAP = tool.Blender.get_tools_to_classes_map() + is_annotation_tool = current_tool.idname == "bim.annotation_tool" + if element.is_a("IfcTypeProduct") or element.is_a("IfcProduct"): element_type = ifcopenshell.util.element.get_type(element) if element_type: is_bim_tool = current_tool.idname == "bim.bim_tool" + + if is_annotation_tool and (object_type := tool.Drawing.get_annotation_type_object_type(element_type)): + aprops.object_type = object_type + aprops.relating_type_id = str(element_type.id()) + return + if is_bim_tool: props.ifc_class = element_type.is_a() + if is_bim_tool or TOOLS_TO_CLASSES_MAP.get(current_tool.idname) == element_type.is_a(): props.relating_type_id = str(element_type.id()) + + if is_annotation_tool: + return + extrusion = tool.Model.get_extrusion(representation) if not extrusion: return diff --git a/src/bonsai/bonsai/bim/module/model/workspace.py b/src/bonsai/bonsai/bim/module/model/workspace.py index b41f155dca..ffb0737015 100644 --- a/src/bonsai/bonsai/bim/module/model/workspace.py +++ b/src/bonsai/bonsai/bim/module/model/workspace.py @@ -1440,8 +1440,6 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator): custom_icon_previews = None display_mode = None -LIST_OF_TOOLS = [cls.bl_idname for cls in (BimTool.__subclasses__() + [BimTool])] -TOOLS_TO_CLASSES_MAP = {cls.bl_idname: cls.ifc_element_type for cls in BimTool.__subclasses__()} MODIFIERS = { "A": ("EVENT_ALT", "OPTION" if sys.platform == "Darwin" else "ALT"), "C": ("EVENT_CTRL", "CTRL"), diff --git a/src/bonsai/bonsai/tool/blender.py b/src/bonsai/bonsai/tool/blender.py index a8a0c0e8b1..ba9974e84f 100644 --- a/src/bonsai/bonsai/tool/blender.py +++ b/src/bonsai/bonsai/tool/blender.py @@ -33,6 +33,7 @@ import types import importlib from mathutils import Vector from pathlib import Path +from functools import lru_cache from bonsai.bim.ifc import IFC_CONNECTED_TYPE from typing import Any, Optional, Union, Literal, Iterable, Callable, TypeVar, Generator from typing_extensions import assert_never @@ -1501,3 +1502,19 @@ class Blender(bonsai.core.tool.Blender): ) for path in paths_to_create: path.mkdir(parents=True, exist_ok=True) + + @classmethod + @lru_cache + def get_list_of_tools(cls) -> tuple[str, ...]: + from bonsai.bim.module.model.workspace import BimTool + from bonsai.bim.module.drawing.workspace import AnnotationTool + + return tuple(cls.bl_idname for cls in (BimTool.__subclasses__() + [BimTool, AnnotationTool])) + + @classmethod + @lru_cache + def get_tools_to_classes_map(cls) -> types.MappingProxyType[str, str]: + from bonsai.bim.module.model.workspace import BimTool + + dct = {cls.bl_idname: cls.ifc_element_type for cls in (BimTool.__subclasses__())} + return types.MappingProxyType(dct) diff --git a/src/bonsai/bonsai/tool/drawing.py b/src/bonsai/bonsai/tool/drawing.py index 439280bf05..134f3bcf5f 100644 --- a/src/bonsai/bonsai/tool/drawing.py +++ b/src/bonsai/bonsai/tool/drawing.py @@ -241,17 +241,22 @@ class Drawing(bonsai.core.tool.Drawing): if element_type == "IfcAnnotation" and element.ObjectType in object_types: return True - if ( - element_type == "IfcTypeProduct" - and element.ApplicableOccurrence - and element.ApplicableOccurrence.startswith("IfcAnnotation/") + if element_type == "IfcTypeProduct" and ( + applicable_object_type := cls.get_annotation_type_object_type(element) ): - applicable_object_type = element.ApplicableOccurrence.split("/")[1] if applicable_object_type in object_types: return True return False + @classmethod + def get_annotation_type_object_type(cls, element_type: ifcopenshell.entity_instance) -> Union[str, None]: + applicable_occurrence: Union[str, None] + applicable_occurrence = element_type.ApplicableOccurrence + if not applicable_occurrence or not applicable_occurrence.startswith("IfcAnnotation/"): + return + return applicable_occurrence.split("/", 1)[1] + @classmethod def get_annotation_representation( cls, element: ifcopenshell.entity_instance