mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-08 08:51:35 +00:00
typing
This commit is contained in:
@@ -38,7 +38,7 @@ import ifcopenshell.util.shape
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.ifc import IfcStore, IFC_CONNECTED_TYPE
|
||||
from bonsai.tool.loader import OBJECT_DATA_TYPE
|
||||
from typing import Dict, Union, Optional, Any, Literal
|
||||
from typing import Dict, Union, Optional, Any, Literal, Iterable
|
||||
from ifcopenshell.util.shape import MatrixType
|
||||
|
||||
|
||||
@@ -319,16 +319,15 @@ class IfcImporter:
|
||||
tool.Loader.settings.gross_context_settings = tool.Loader.create_settings(is_gross=True)
|
||||
|
||||
def process_element_filter(self) -> None:
|
||||
elements: list[ifcopenshell.entity_instance]
|
||||
if self.ifc_import_settings.has_filter:
|
||||
self.elements = self.ifc_import_settings.elements
|
||||
if isinstance(self.elements, set):
|
||||
self.elements = list(self.elements)
|
||||
elements = list(self.ifc_import_settings.elements)
|
||||
# TODO: enable filtering for annotations
|
||||
else:
|
||||
if self.file.schema in ("IFC2X3", "IFC4"):
|
||||
self.elements = self.file.by_type("IfcElement") + self.file.by_type("IfcProxy")
|
||||
elements = self.file.by_type("IfcElement") + self.file.by_type("IfcProxy")
|
||||
else:
|
||||
self.elements = self.file.by_type("IfcElement")
|
||||
elements = self.file.by_type("IfcElement")
|
||||
|
||||
drawing_groups = [g for g in self.file.by_type("IfcGroup") if g.ObjectType == "DRAWING"]
|
||||
drawing_annotations = set()
|
||||
@@ -338,16 +337,16 @@ class IfcImporter:
|
||||
self.annotations = set([a for a in self.file.by_type("IfcAnnotation")])
|
||||
self.annotations -= drawing_annotations
|
||||
|
||||
self.elements = [e for e in self.elements if not e.is_a("IfcFeatureElement") or e.is_a("IfcSurfaceFeature")]
|
||||
elements = [e for e in elements if not e.is_a("IfcFeatureElement") or e.is_a("IfcSurfaceFeature")]
|
||||
if self.ifc_import_settings.element_limit_mode == "UNLIMITED":
|
||||
self.elements = set(self.elements)
|
||||
self.elements = set(elements)
|
||||
else:
|
||||
offset = self.ifc_import_settings.element_offset
|
||||
offset_limit = offset + self.ifc_import_settings.element_limit
|
||||
self.elements = set(self.elements[offset:offset_limit])
|
||||
self.elements = set(elements[offset:offset_limit])
|
||||
|
||||
if self.ifc_import_settings.has_filter or self.ifc_import_settings.element_limit_mode != "UNLIMITED":
|
||||
self.element_types = set([ifcopenshell.util.element.get_type(e) for e in self.elements])
|
||||
self.element_types = {t for e in self.elements if (t := ifcopenshell.util.element.get_type(e))}
|
||||
else:
|
||||
self.element_types = set(self.file.by_type("IfcTypeProduct"))
|
||||
|
||||
@@ -1168,13 +1167,13 @@ class IfcImportSettings:
|
||||
self.element_limit_mode = "UNLIMITED"
|
||||
self.element_offset = 0
|
||||
self.element_limit = 30000
|
||||
self.has_filter = None
|
||||
self.has_filter = False
|
||||
self.should_filter_spatial_elements = True
|
||||
self.should_setup_viewport_camera = True
|
||||
self.contexts: list[ifcopenshell.entity_instance] = []
|
||||
self.context_settings: list[ifcopenshell.geom.main.settings] = []
|
||||
self.gross_context_settings: list[ifcopenshell.geom.main.settings] = []
|
||||
self.elements: set[ifcopenshell.entity_instance] = set()
|
||||
self.elements: Iterable[ifcopenshell.entity_instance] = set()
|
||||
self.load_indexed_maps = False
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -1736,13 +1736,14 @@ class OverrideJoin(bpy.types.Operator, tool.Ifc.Operator):
|
||||
)
|
||||
|
||||
def join_blender_obj(self) -> None:
|
||||
ifc_file = tool.Ifc.get()
|
||||
for obj in bpy.context.selected_objects:
|
||||
if obj == self.target:
|
||||
continue
|
||||
# TODO Properly handle element types, grid axes, and representation items
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if element:
|
||||
ifcopenshell.api.run("root.remove_product", tool.Ifc.get(), product=element)
|
||||
ifcopenshell.api.root.remove_product(ifc_file, product=element)
|
||||
bpy.ops.object.join()
|
||||
|
||||
|
||||
|
||||
@@ -162,6 +162,11 @@ class RepresentationItemObject(PropertyGroup):
|
||||
obj: PointerProperty(type=bpy.types.Object)
|
||||
ifc_definition_id: IntProperty()
|
||||
|
||||
if TYPE_CHECKING:
|
||||
name: str
|
||||
obj: Union[bpy.types.Object, None]
|
||||
ifc_definition_id: int
|
||||
|
||||
|
||||
class ShapeAspect(PropertyGroup):
|
||||
name: StringProperty(
|
||||
|
||||
@@ -1103,8 +1103,8 @@ class LoadProjectElements(bpy.types.Operator):
|
||||
bonsai.bim.handler.refresh_ui_data()
|
||||
return {"FINISHED"}
|
||||
|
||||
def get_decomposition_elements(self):
|
||||
containers = set()
|
||||
def get_decomposition_elements(self) -> set[ifcopenshell.entity_instance]:
|
||||
containers: set[ifcopenshell.entity_instance] = set()
|
||||
for filter_category in self.props.filter_categories:
|
||||
if not filter_category.is_selected:
|
||||
continue
|
||||
@@ -1116,15 +1116,15 @@ class LoadProjectElements(bpy.types.Operator):
|
||||
container = None
|
||||
elif self.file.schema != "IFC2X3" and container.is_a("IfcContext"):
|
||||
container = None
|
||||
elements = set()
|
||||
elements: set[ifcopenshell.entity_instance] = set()
|
||||
for container in containers:
|
||||
for rel in container.ContainsElements:
|
||||
elements.update(rel.RelatedElements)
|
||||
self.append_decomposed_elements(elements)
|
||||
return elements
|
||||
|
||||
def append_decomposed_elements(self, elements):
|
||||
decomposed_elements = set()
|
||||
def append_decomposed_elements(self, elements: set[ifcopenshell.entity_instance]) -> None:
|
||||
decomposed_elements: set[ifcopenshell.entity_instance] = set()
|
||||
for element in elements:
|
||||
if element.IsDecomposedBy:
|
||||
for subelement in element.IsDecomposedBy[0].RelatedObjects:
|
||||
@@ -1133,26 +1133,26 @@ class LoadProjectElements(bpy.types.Operator):
|
||||
self.append_decomposed_elements(decomposed_elements)
|
||||
elements.update(decomposed_elements)
|
||||
|
||||
def get_ifc_class_elements(self):
|
||||
elements = set()
|
||||
def get_ifc_class_elements(self) -> set[ifcopenshell.entity_instance]:
|
||||
elements: set[ifcopenshell.entity_instance] = set()
|
||||
for filter_category in self.props.filter_categories:
|
||||
if not filter_category.is_selected:
|
||||
continue
|
||||
elements.update(self.file.by_type(filter_category.name, include_subtypes=False))
|
||||
return elements
|
||||
|
||||
def get_ifc_type_elements(self):
|
||||
elements = set()
|
||||
def get_ifc_type_elements(self) -> set[ifcopenshell.entity_instance]:
|
||||
elements: set[ifcopenshell.entity_instance] = set()
|
||||
for filter_category in self.props.filter_categories:
|
||||
if not filter_category.is_selected:
|
||||
continue
|
||||
elements.update(ifcopenshell.util.element.get_types(self.file.by_id(filter_category.ifc_definition_id)))
|
||||
return elements
|
||||
|
||||
def get_whitelist_elements(self):
|
||||
def get_whitelist_elements(self) -> set[ifcopenshell.entity_instance]:
|
||||
return set(ifcopenshell.util.selector.filter_elements(self.file, self.props.filter_query))
|
||||
|
||||
def get_blacklist_elements(self):
|
||||
def get_blacklist_elements(self) -> set[ifcopenshell.entity_instance]:
|
||||
return set(self.file.by_type("IfcElement")) - set(
|
||||
ifcopenshell.util.selector.filter_elements(self.file, self.props.filter_query)
|
||||
)
|
||||
|
||||
@@ -67,6 +67,7 @@ from typing import (
|
||||
Generator,
|
||||
cast,
|
||||
TypeGuard,
|
||||
Any,
|
||||
)
|
||||
from typing_extensions import TypeIs
|
||||
|
||||
@@ -1861,6 +1862,7 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
tool.Blender.set_active_object(props.representation_obj)
|
||||
cls.sync_item_positions()
|
||||
representation = cls.get_active_representation(props.representation_obj)
|
||||
assert representation
|
||||
ifcopenshell.api.geometry.validate_type(tool.Ifc.get(), representation)
|
||||
props.is_changing_mode = True
|
||||
if props.mode != "OBJECT":
|
||||
@@ -1873,6 +1875,7 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
def edit_meshlike_item(cls, obj: bpy.types.Object) -> None:
|
||||
item = tool.Geometry.get_active_representation(obj)
|
||||
assert item
|
||||
assert isinstance(obj.data, (bpy.types.Curve, bpy.types.Mesh))
|
||||
mprops = tool.Geometry.get_mesh_props(obj.data)
|
||||
if mprops.mesh_checksum == cls.get_mesh_checksum(obj.data):
|
||||
return
|
||||
@@ -1898,7 +1901,7 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
ifcopenshell.util.element.replace_attribute(inverse, item, new_item)
|
||||
ifcopenshell.util.element.remove_deep2(tool.Ifc.get(), item)
|
||||
tool.Ifc.link(new_item, obj.data)
|
||||
cls.reload_representation(props.representation_obj)
|
||||
cls.reload_representation(rep_obj)
|
||||
|
||||
@classmethod
|
||||
def split_by_loose_parts(cls, obj: bpy.types.Object) -> List[bpy.types.Mesh]:
|
||||
@@ -2130,7 +2133,6 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
tool.Root.reload_grid_decorator()
|
||||
return old_to_new, new_active_obj or active_object
|
||||
|
||||
|
||||
@classmethod
|
||||
def duplicate_ifc_item(cls, obj: bpy.types.Object) -> None:
|
||||
props = tool.Geometry.get_geometry_props()
|
||||
@@ -2148,11 +2150,13 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
for collection in obj.users_collection:
|
||||
collection.objects.link(new_obj)
|
||||
|
||||
representation = tool.Geometry.get_active_representation(props.representation_obj)
|
||||
assert (rep_obj := props.representation_obj)
|
||||
representation = tool.Geometry.get_active_representation(rep_obj)
|
||||
assert representation
|
||||
representation = ifcopenshell.util.representation.resolve_representation(representation)
|
||||
representation.Items = list(representation.Items) + [new_item]
|
||||
|
||||
tool.Geometry.reload_representation(props.representation_obj)
|
||||
tool.Geometry.reload_representation(rep_obj)
|
||||
|
||||
obj.select_set(False)
|
||||
tool.Root.reload_item_decorator()
|
||||
|
||||
@@ -47,7 +47,7 @@ def validate_type(
|
||||
combination, or False otherwise.
|
||||
"""
|
||||
|
||||
def is_operand(item):
|
||||
def is_operand(item: ifcopenshell.entity_instance) -> bool:
|
||||
return (
|
||||
item.is_a("IfcBooleanResult")
|
||||
or item.is_a("IfcCsgPrimitive3D")
|
||||
|
||||
Reference in New Issue
Block a user