Update Annotation Tool types when selecting elements #6134

Similar to other BIM Tools

Update handler.py
This commit is contained in:
Andrej730
2025-02-10 14:16:59 +05:00
parent 4c0a7e1ca9
commit d8a250f153
4 changed files with 44 additions and 10 deletions
+17 -3
View File
@@ -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
@@ -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"),
+17
View File
@@ -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)
+10 -5
View File
@@ -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