This commit is contained in:
Andrej730
2025-02-03 12:53:08 +05:00
parent 734cd47ea5
commit a48d774337
13 changed files with 222 additions and 81 deletions
@@ -100,7 +100,7 @@ classes = (
prop.Sheet,
prop.DocProperties,
prop.BIMCameraProperties,
prop.Literal,
prop.LiteralProps,
prop.BIMTextProperties,
prop.BIMAssignedProductProperties,
prop.BIMAnnotationProperties,
@@ -1686,7 +1686,7 @@ class RemoveDrawingFromSheet(bpy.types.Operator, tool.Ifc.Operator):
return False
if active_item.reference_type == "TITLEBLOCK":
cls.poll_message_set("No effect deleting this.")
cls.poll_message_set("No effect deleting titleblock reference.")
return False
return True
+66 -2
View File
@@ -44,6 +44,7 @@ from bpy.props import (
CollectionProperty,
BoolVectorProperty,
)
from typing import TYPE_CHECKING, Literal
diagram_scales_enum = []
@@ -294,12 +295,25 @@ class Drawing(PropertyGroup):
is_drawing: BoolProperty(name="Is Drawing", default=False)
is_expanded: BoolProperty(name="Is Expanded", default=True)
if TYPE_CHECKING:
ifc_definition_id: int
name: str
target_view: str
is_selected: bool
is_drawing: bool
is_expanded: bool
class Document(PropertyGroup):
ifc_definition_id: IntProperty(name="IFC Definition ID")
name: StringProperty(name="Name", update=update_document_name)
identification: StringProperty(name="Identification")
if TYPE_CHECKING:
ifc_definition_id: int
name: str
identification: str
class Sheet(PropertyGroup):
ifc_definition_id: IntProperty(name="IFC Definition ID")
@@ -310,6 +324,15 @@ class Sheet(PropertyGroup):
reference_type: StringProperty(name="Reference Type")
is_expanded: BoolProperty(name="Is Expanded", default=False)
if TYPE_CHECKING:
ifc_definition_id: int
identification: str
name: str
is_sheet: bool
is_selected: bool
reference_type: str
is_expanded: bool
class DrawingStyle(PropertyGroup):
name: StringProperty(name="Name", get=get_drawing_style_name, set=set_drawing_style_name)
@@ -408,6 +431,47 @@ class DocProperties(PropertyGroup):
description="Upon import, these classes will display as wireframe.\nEx: IfcVirtualelement, IfcSpace",
)
if TYPE_CHECKING:
should_use_underlay_cache: bool
should_use_linework_cache: bool
should_use_annotation_cache: bool
is_editing_drawings: bool
is_editing_schedules: bool
is_editing_references: bool
target_view: Literal["PLAN_VIEW", "ELEVATION_VIEW", "SECTION_VIEW", "REFLECTED_PLAN_VIEW", "MODEL_VIEW"]
location_hint: str
drawings: bpy.types.bpy_prop_collection_idprop[Drawing]
active_drawing_id: int
active_drawing_index: int
current_drawing_index: int
schedules: bpy.types.bpy_prop_collection_idprop[Document]
active_schedule_index: int
references: bpy.types.bpy_prop_collection_idprop[Document]
active_reference_index: int
titleblock: str
is_editing_sheets: bool
sheets: bpy.types.bpy_prop_collection_idprop[Sheet]
active_sheet_index: int
ifc_files: bpy.types.bpy_prop_collection_idprop[StrProperty]
drawing_styles: bpy.types.bpy_prop_collection_idprop[DrawingStyle]
should_draw_decorations: bool
sheets_dir: str
layouts_dir: str
titleblocks_dir: str
drawings_dir: str
stylesheet_path: str
schedules_stylesheet_path: str
markers_path: str
symbols_path: str
patterns_path: str
shadingstyles_path: str
shadingstyle_default: str
drawing_font: str
magic_font_scale: float
imperial_precision: str
tolerance: float
classes_to_wireframe: str
class BIMCameraProperties(PropertyGroup):
linework_mode: EnumProperty(
@@ -490,7 +554,7 @@ BOX_ALIGNMENT_POSITIONS = [
]
class Literal(PropertyGroup):
class LiteralProps(PropertyGroup):
def set_box_alignment(self, new_value):
markers = new_value.count(True)
if not markers:
@@ -535,7 +599,7 @@ class Literal(PropertyGroup):
class BIMTextProperties(PropertyGroup):
is_editing: BoolProperty(name="Is Editing", default=False)
literals: CollectionProperty(name="Literals", type=Literal)
literals: CollectionProperty(name="Literals", type=LiteralProps)
font_size: EnumProperty(
items=[
("1.8", "1.8 - Small", ""),
@@ -1075,7 +1075,7 @@ class OverrideDuplicateMove(bpy.types.Operator):
@staticmethod
def duplicate_item(obj: bpy.types.Object) -> None:
props = bpy.context.scene.BIMGeometryProperties
props = tool.Geometry.get_geometry_props()
item = tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
new_item = ifcopenshell.util.element.copy_deep(tool.Ifc.get(), item)
new_obj = obj.copy()
@@ -2750,17 +2750,17 @@ class ImportRepresentationItems(bpy.types.Operator, tool.Ifc.Operator):
def _execute(self, context):
obj = context.active_object
assert obj
props = context.scene.BIMGeometryProperties
props = tool.Geometry.get_geometry_props()
if previous_obj := props.representation_obj:
previous_obj.hide_set(False)
props.representation_obj = obj
obj.hide_set(True)
tool.Geometry.lock_object(obj)
context.scene.BIMGeometryProperties.is_changing_mode = True
if context.scene.BIMGeometryProperties.mode != "ITEM":
context.scene.BIMGeometryProperties.mode = "ITEM"
context.scene.BIMGeometryProperties.is_changing_mode = False
props.is_changing_mode = True
if props.mode != "ITEM":
props.mode = "ITEM"
props.is_changing_mode = False
tool.Loader.load_settings()
+11 -1
View File
@@ -32,7 +32,7 @@ from bpy.props import (
FloatVectorProperty,
CollectionProperty,
)
from typing import Optional, TYPE_CHECKING
from typing import Optional, TYPE_CHECKING, Union
def get_contexts(self, context):
@@ -302,3 +302,13 @@ class BIMGeometryProperties(PropertyGroup):
type=bpy.types.Object,
poll=is_object_valid_for_representation_copy,
)
if TYPE_CHECKING:
should_use_presentation_style_assignment: bool
should_force_faceted_brep: bool
should_force_triangulation: bool
is_changing_mode: bool
mode: str
representation_obj: Union[bpy.types.Object, None]
item_objs: bpy.types.bpy_prop_collection_idprop[RepresentationItemObject]
representation_from_object: Union[bpy.types.Object, None]
@@ -1243,7 +1243,7 @@ class LoadLink(bpy.types.Operator):
os.remove(blend_filepath)
if not blend_filepath.exists():
pprops = bpy.context.scene.BIMProjectProperties
pprops = tool.Project.get_project_props()
gprops = bpy.context.scene.BIMGeoreferenceProperties
code = f"""
@@ -337,7 +337,7 @@ class LoadZones(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
props = bpy.context.scene.BIMZoneProperties
props = tool.System.get_zone_props()
props.zones.clear()
for zone in tool.Ifc.get().by_type("IfcZone"):
new = props.zones.add()
@@ -354,7 +354,7 @@ class UnloadZones(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
props = bpy.context.scene.BIMZoneProperties
props = tool.System.get_zone_props()
props.is_loaded = False
return {"FINISHED"}
@@ -386,7 +386,7 @@ class EnableEditingZone(bpy.types.Operator):
zone: bpy.props.IntProperty()
def execute(self, context):
props = bpy.context.scene.BIMZoneProperties
props = tool.System.get_zone_props()
props.attributes.clear()
bonsai.bim.helper.import_attributes2(tool.Ifc.get().by_id(self.zone), props.attributes)
props.is_editing = self.zone
@@ -399,7 +399,7 @@ class DisableEditingZone(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
props = bpy.context.scene.BIMZoneProperties
props = tool.System.get_zone_props()
props.is_editing = 0
return {"FINISHED"}
@@ -410,7 +410,7 @@ class EditZone(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
props = bpy.context.scene.BIMZoneProperties
props = tool.System.get_zone_props()
zone = tool.Ifc.get().by_id(props.is_editing)
attributes = bonsai.bim.helper.export_attributes(props.attributes)
ifcopenshell.api.run("system.edit_system", tool.Ifc.get(), system=zone, attributes=attributes)
@@ -31,6 +31,7 @@ from bpy.props import (
FloatVectorProperty,
CollectionProperty,
)
from typing import TYPE_CHECKING
def get_system_class(self, context):
@@ -71,6 +72,17 @@ class BIMSystemProperties(PropertyGroup):
name="Should Draw Decorations", description="Toggle system decorations", update=toggle_decorations
)
if TYPE_CHECKING:
system_attributes: bpy.types.bpy_prop_collection_idprop[Attribute]
is_editing: bool
is_adding: bool
systems: bpy.types.bpy_prop_collection_idprop[System]
active_system_index: int
active_system_id: int
edited_system_id: int
system_class: str
should_draw_decorations: bool
class BIMZoneProperties(PropertyGroup):
attributes: CollectionProperty(name="Attributes", type=Attribute)
@@ -78,3 +90,10 @@ class BIMZoneProperties(PropertyGroup):
is_editing: IntProperty(name="Is Editing", default=0)
zones: CollectionProperty(name="Zones", type=Zone)
active_zone_index: IntProperty(name="Active Zone Index")
if TYPE_CHECKING:
attributes: bpy.types.bpy_prop_collection_idprop[Attribute]
is_loaded: bool
is_editing: int
zones: bpy.types.bpy_prop_collection_idprop[Zone]
active_zone_index: int
+2 -2
View File
@@ -350,7 +350,7 @@ class BIM_PT_zones(Panel):
def draw(self, context):
if not ZonesData.is_loaded:
ZonesData.load()
self.props = context.scene.BIMZoneProperties
self.props = tool.System.get_zone_props()
row = self.layout.row(align=True)
row.label(text="{} Zones Found".format(ZonesData.data["total_zones"]), icon="SEQ_STRIP_META")
@@ -394,7 +394,7 @@ class BIM_PT_active_object_zones(Panel):
def draw(self, context):
if not ActiveObjectZonesData.is_loaded:
ActiveObjectZonesData.load()
self.props = context.scene.BIMZoneProperties
self.props = tool.System.get_zone_props()
for zone in ActiveObjectZonesData.data["zones"]:
row = self.layout.row()
+27 -17
View File
@@ -16,58 +16,68 @@
# You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
from typing import TYPE_CHECKING, Optional
def load_systems(system):
if TYPE_CHECKING:
import bpy
import ifcopenshell
import bonsai.tool as tool
def load_systems(system: tool.System) -> None:
system.import_systems()
system.enable_system_editing_ui()
system.disable_editing_system()
def disable_system_editing_ui(system):
def disable_system_editing_ui(system: tool.System) -> None:
system.disable_editing_system()
system.disable_system_editing_ui()
def add_system(ifc, system, ifc_class=None):
def add_system(ifc: tool.Ifc, system: tool.System, ifc_class: str) -> None:
ifc.run("system.add_system", ifc_class=ifc_class)
system.import_systems()
def edit_system(ifc, system_tool, system=None):
def edit_system(ifc: tool.Ifc, system_tool: tool.System, system: ifcopenshell.entity_instance) -> None:
attributes = system_tool.export_system_attributes()
ifc.run("system.edit_system", system=system, attributes=attributes)
system_tool.disable_editing_system()
system_tool.import_systems()
def remove_system(ifc, system_tool, system=None):
def remove_system(ifc: tool.Ifc, system_tool: tool.System, system: ifcopenshell.entity_instance) -> None:
ifc.run("system.remove_system", system=system)
system_tool.import_systems()
def enable_editing_system(system_tool, system=None):
def enable_editing_system(system_tool: tool.System, system: ifcopenshell.entity_instance) -> None:
system_tool.import_system_attributes(system)
system_tool.set_active_edited_system(system)
def disable_editing_system(system):
def disable_editing_system(system: tool.System) -> None:
system.disable_editing_system()
def assign_system(ifc, system=None, product=None):
def assign_system(ifc: tool.Ifc, system: ifcopenshell.entity_instance, product: ifcopenshell.entity_instance) -> None:
ifc.run("system.assign_system", products=[product], system=system)
def unassign_system(ifc, system=None, product=None):
def unassign_system(ifc: tool.Ifc, system: ifcopenshell.entity_instance, product: ifcopenshell.entity_instance) -> None:
ifc.run("system.unassign_system", products=[product], system=system)
def select_system_products(system_tool, system=None):
def select_system_products(system_tool: tool.System, system: ifcopenshell.entity_instance) -> None:
system_tool.select_system_products(system)
system_tool.set_active_system(system)
def show_ports(ifc, system, spatial, element=None):
def show_ports(
ifc: tool.Ifc, system: tool.System, spatial: tool.Spatial, element: ifcopenshell.entity_instance
) -> None:
obj = ifc.get_object(element)
if obj and ifc.is_moved(obj):
system.run_geometry_edit_object_placement(obj=obj)
@@ -77,7 +87,7 @@ def show_ports(ifc, system, spatial, element=None):
spatial.select_products(ports)
def hide_ports(ifc, system, element=None):
def hide_ports(ifc: tool.Ifc, system: tool.System, element: ifcopenshell.entity_instance) -> None:
obj = ifc.get_object(element)
if obj and ifc.is_moved(obj):
system.run_geometry_edit_object_placement(obj=obj)
@@ -91,27 +101,27 @@ def hide_ports(ifc, system, element=None):
system.delete_element_objects(ports)
def add_port(ifc, system, element=None):
def add_port(ifc: tool.Ifc, system: tool.System, element: ifcopenshell.entity_instance) -> None:
system.load_ports(element, system.get_ports(element))
obj = system.create_empty_at_cursor_with_element_orientation(element)
port = system.run_root_assign_class(obj=obj, ifc_class="IfcDistributionPort", should_add_representation=False)
ifc.run("system.assign_port", element=element, port=port)
def remove_port(ifc, system, port=None):
def remove_port(ifc: tool.Ifc, system: tool.System, port: ifcopenshell.entity_instance) -> None:
system.delete_element_objects([port])
ifc.run("root.remove_product", product=port)
def connect_port(ifc, port1=None, port2=None):
def connect_port(ifc: tool.Ifc, port1: ifcopenshell.entity_instance, port2: ifcopenshell.entity_instance) -> None:
ifc.run("system.connect_port", port1=port1, port2=port2)
def disconnect_port(ifc, port=None):
def disconnect_port(ifc: tool.Ifc, port: ifcopenshell.entity_instance) -> None:
ifc.run("system.disconnect_port", port=port)
def set_flow_direction(ifc, system, port=None, direction=None):
def set_flow_direction(ifc: tool.Ifc, system: tool.System, port: ifcopenshell.entity_instance, direction: str) -> None:
port2 = system.get_connected_port(port)
if not port2:
return
+19 -11
View File
@@ -16,6 +16,7 @@
# You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import os
import re
import collections
@@ -34,6 +35,7 @@ import subprocess
import numpy as np
import bonsai.core.tool
import bonsai.core.geometry
import bonsai.core.type
import bonsai.tool as tool
import ifcopenshell.api
import ifcopenshell.api.document
@@ -49,9 +51,13 @@ from shapely.ops import unary_union
from lxml import etree
from mathutils import Vector, Matrix
from fractions import Fraction
from typing import Optional, Union, Iterable, Any, Literal, Sequence
from typing import Optional, Union, Iterable, Any, Literal, Sequence, TYPE_CHECKING
from pathlib import Path
if TYPE_CHECKING:
from bonsai.bim.module.drawing.prop import DocProperties, Sheet
from bonsai.bim.module.drawing.prop import Drawing as DrawingProperties
class Drawing(bonsai.core.tool.Drawing):
ANNOTATION_DATA_TYPE = Literal["empty", "curve", "mesh"]
@@ -81,6 +87,10 @@ class Drawing(bonsai.core.tool.Drawing):
}
# fmt: on
@classmethod
def get_document_props(cls) -> DocProperties:
return bpy.context.scene.DocProperties
@classmethod
def canonicalise_class_name(cls, name: str) -> str:
return re.sub("[^0-9a-zA-Z]+", "", name)
@@ -820,7 +830,7 @@ class Drawing(bonsai.core.tool.Drawing):
@classmethod
def import_documents(cls, document_type: DOCUMENT_TYPE) -> None:
dprops = bpy.context.scene.DocProperties
dprops = cls.get_document_props()
if document_type == "SCHEDULE":
documents_collection = dprops.schedules
elif document_type == "REFERENCE":
@@ -839,7 +849,7 @@ class Drawing(bonsai.core.tool.Drawing):
@classmethod
def import_sheets(cls) -> None:
props = bpy.context.scene.DocProperties
props = cls.get_document_props()
expanded_sheets = {s.ifc_definition_id for s in props.sheets if s.is_expanded}
if not hasattr(cls, "sheet_selected_states"):
cls.sheet_selected_states = {}
@@ -879,13 +889,13 @@ class Drawing(bonsai.core.tool.Drawing):
new.reference_type = reference_description
@classmethod
def get_active_sheet(cls, context: bpy.types.Context) -> bpy.types.PropertyGroup:
props = context.scene.DocProperties
def get_active_sheet(cls, context: bpy.types.Context) -> Sheet:
props = cls.get_document_props()
return next(s for s in props.sheets[: props.active_sheet_index + 1][::-1] if s.is_sheet)
@classmethod
def get_active_drawing_item(cls) -> Union[bpy.types.PropertyGroup, None]:
props = bpy.context.scene.DocProperties
def get_active_drawing_item(cls) -> Union[DrawingProperties, None]:
props = cls.get_document_props()
drawing_index = props.active_drawing_index
if len(props.drawings) > drawing_index >= 0:
item = props.drawings[drawing_index]
@@ -893,10 +903,8 @@ class Drawing(bonsai.core.tool.Drawing):
return item
@classmethod
def get_active_sheet_item(
cls, *, is_sheet: bool = False, reference_type: str = ""
) -> Union[bpy.types.PropertyGroup, None]:
props = bpy.context.scene.DocProperties
def get_active_sheet_item(cls, *, is_sheet: bool = False, reference_type: str = "") -> Union[Sheet, None]:
props = cls.get_document_props()
sheet_index = props.active_sheet_index
if len(props.sheets) > sheet_index >= 0:
item = props.sheets[sheet_index]
+5 -1
View File
@@ -57,10 +57,14 @@ from typing_extensions import TypeIs
if TYPE_CHECKING:
from bonsai.bim.prop import Attribute
from bonsai.bim.module.geometry.prop import BIMObjectGeometryProperties
from bonsai.bim.module.geometry.prop import BIMObjectGeometryProperties, BIMGeometryProperties
class Geometry(bonsai.core.tool.Geometry):
@classmethod
def get_geometry_props(cls) -> BIMGeometryProperties:
return bpy.context.scene.BIMGeometryProperties
@classmethod
def get_object_geometry_props(cls, object: bpy.types.Object) -> BIMObjectGeometryProperties:
return object.BIMGeometryProperties
+59 -33
View File
@@ -16,6 +16,7 @@
# You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import bpy
import ifcopenshell.util.element
import ifcopenshell.util.system
@@ -31,11 +32,30 @@ from mathutils import Matrix, Vector
from bonsai.bim.module.system.data import ObjectSystemData, SystemDecorationData
from bonsai.bim.module.drawing.decoration import profile_consequential
from enum import Enum
from typing import TYPE_CHECKING, Optional, Any, Union
if TYPE_CHECKING:
from bonsai.bim.module.system.prop import BIMSystemProperties, BIMZoneProperties
class System(bonsai.core.tool.System):
@classmethod
def add_ports(cls, obj, add_start_port=True, add_end_port=True, end_port_pos=None, offset_end_port=None):
def get_system_props(cls) -> BIMSystemProperties:
return bpy.context.scene.BIMSystemProperties
@classmethod
def get_zone_props(cls) -> BIMZoneProperties:
return bpy.context.scene.BIMZoneProperties
@classmethod
def add_ports(
cls,
obj: bpy.types.Object,
add_start_port: bool = True,
add_end_port: bool = True,
end_port_pos: Optional[Vector] = None,
offset_end_port: Optional[Vector] = None,
) -> list[ifcopenshell.entity_instance]:
def add_port(mep_element, matrix):
port = tool.Ifc.run("system.add_port", element=mep_element)
port.FlowDirection = "NOTDEFINED"
@@ -66,7 +86,7 @@ class System(bonsai.core.tool.System):
return ports
@classmethod
def create_empty_at_cursor_with_element_orientation(cls, element):
def create_empty_at_cursor_with_element_orientation(cls, element: ifcopenshell.entity_instance) -> bpy.types.Object:
element_obj = tool.Ifc.get_object(element)
obj = bpy.data.objects.new("Port", None)
obj.matrix_world = element_obj.matrix_world
@@ -75,38 +95,38 @@ class System(bonsai.core.tool.System):
return obj
@classmethod
def delete_element_objects(cls, elements):
def delete_element_objects(cls, elements: list[ifcopenshell.entity_instance]) -> None:
for element in elements:
obj = tool.Ifc.get_object(element)
if obj:
bpy.data.objects.remove(obj)
@classmethod
def disable_editing_system(cls):
bpy.context.scene.BIMSystemProperties.edited_system_id = 0
def disable_editing_system(cls) -> None:
cls.get_system_props().edited_system_id = 0
@classmethod
def disable_system_editing_ui(cls):
bpy.context.scene.BIMSystemProperties.is_editing = False
def disable_system_editing_ui(cls) -> None:
cls.get_system_props().is_editing = False
@classmethod
def enable_system_editing_ui(cls):
bpy.context.scene.BIMSystemProperties.is_editing = True
def enable_system_editing_ui(cls) -> None:
cls.get_system_props().is_editing = True
@classmethod
def export_system_attributes(cls):
return bonsai.bim.helper.export_attributes(bpy.context.scene.BIMSystemProperties.system_attributes)
def export_system_attributes(cls) -> dict[str, Any]:
return bonsai.bim.helper.export_attributes(cls.get_system_props().system_attributes)
@classmethod
def get_connected_port(cls, port):
def get_connected_port(cls, port: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
return ifcopenshell.util.system.get_connected_port(port)
@classmethod
def get_ports(cls, element):
def get_ports(cls, element: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
return ifcopenshell.util.system.get_ports(element)
@classmethod
def get_port_relating_element(cls, port):
def get_port_relating_element(cls, port: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
if tool.Ifc.get_schema() == "IFC2X3":
element = port.ContainedIn[0].RelatedElement
else:
@@ -114,7 +134,7 @@ class System(bonsai.core.tool.System):
return element
@classmethod
def get_port_predefined_type(cls, mep_element):
def get_port_predefined_type(cls, mep_element: ifcopenshell.entity_instance) -> str:
split_camel_case = lambda x: re.findall("[A-Z][^A-Z]*", x)
mep_class = mep_element.is_a()
if mep_class.endswith("Type"):
@@ -125,20 +145,20 @@ class System(bonsai.core.tool.System):
return class_name
@classmethod
def import_system_attributes(cls, system):
props = bpy.context.scene.BIMSystemProperties
def import_system_attributes(cls, system: ifcopenshell.entity_instance) -> None:
props = cls.get_system_props()
props.system_attributes.clear()
bonsai.bim.helper.import_attributes2(system, props.system_attributes)
@classmethod
def get_systems(cls):
def get_systems(cls) -> list[ifcopenshell.entity_instance]:
if tool.Ifc.get_schema() == "IFC2X3":
return tool.Ifc.get().by_type("IfcSystem") + tool.Ifc.get().by_type("IfcZone")
return tool.Ifc.get().by_type("IfcSystem")
@classmethod
def import_systems(cls):
props = bpy.context.scene.BIMSystemProperties
def import_systems(cls) -> None:
props = cls.get_system_props()
props.systems.clear()
for system in cls.get_systems():
if system.is_a() in ["IfcStructuralAnalysisModel"]:
@@ -179,7 +199,7 @@ class System(bonsai.core.tool.System):
port_obj.matrix_parent_inverse = obj.matrix_world.inverted()
@classmethod
def run_geometry_edit_object_placement(cls, obj=None):
def run_geometry_edit_object_placement(cls, obj: bpy.types.Object) -> None:
return bonsai.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj)
@classmethod
@@ -205,24 +225,24 @@ class System(bonsai.core.tool.System):
)
@classmethod
def select_system_products(cls, system):
def select_system_products(cls, system: ifcopenshell.entity_instance) -> None:
tool.Spatial.select_products(ifcopenshell.util.system.get_system_elements(system))
@classmethod
def set_active_edited_system(cls, system):
bpy.context.scene.BIMSystemProperties.edited_system_id = system.id()
def set_active_edited_system(cls, system: ifcopenshell.entity_instance) -> None:
cls.get_system_props().edited_system_id = system.id()
@classmethod
def set_active_system(cls, system):
bpy.context.scene.BIMSystemProperties.active_system_id = system.id()
def set_active_system(cls, system: ifcopenshell.entity_instance) -> None:
cls.get_system_props().active_system_id = system.id()
@classmethod
def get_active_system(cls):
system_props = bpy.context.scene.BIMSystemProperties
def get_active_system(cls) -> Union[ifcopenshell.entity_instance, None]:
system_props = cls.get_system_props()
return tool.Ifc.get_entity_by_id(system_props.active_system_id)
@classmethod
def get_decoration_data(cls):
def get_decoration_data(cls) -> dict[str, Any]:
all_vertices = []
preview_edges = []
special_vertices = []
@@ -367,7 +387,11 @@ class System(bonsai.core.tool.System):
return decoration_data
@classmethod
def get_connected_elements(cls, element, traversed_elements=None):
def get_connected_elements(
cls,
element: ifcopenshell.entity_instance,
traversed_elements: Optional[set[ifcopenshell.entity_instance]] = None,
) -> set[ifcopenshell.entity_instance]:
"""Recursively retrieves all connected elements to the given `element`.
`traversed_elements` is a set to store connected elements fetched recursively,
@@ -387,17 +411,19 @@ class System(bonsai.core.tool.System):
return traversed_elements
@classmethod
def is_mep_element(cls, element):
def is_mep_element(cls, element: ifcopenshell.entity_instance) -> bool:
return element.is_a("IfcFlowSegment") or element.is_a("IfcFlowFitting")
@classmethod
def get_flow_element_controls(cls, element):
def get_flow_element_controls(cls, element: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
if not element.HasControlElements:
return []
return [control for control in element.HasControlElements[0].RelatedControlElements]
@classmethod
def get_flow_control_flow_element(cls, element):
def get_flow_control_flow_element(
cls, element: ifcopenshell.entity_instance
) -> Union[ifcopenshell.entity_instance, None]:
if not element.AssignedToFlowElement:
return
return element.AssignedToFlowElement[0].RelatingFlowElement