This commit is contained in:
Andrej730
2024-03-13 15:21:26 +05:00
parent 9596117953
commit 28b54c869a
3 changed files with 42 additions and 33 deletions
+8 -6
View File
@@ -29,14 +29,14 @@ import blenderbim.bim.handler
import blenderbim.tool as tool
from pathlib import Path
from blenderbim.tool.brick import BrickStore
from typing import Set, Union
from typing import Set, Union, Optional
IFC_CONNECTED_TYPE = Union[bpy.types.Material, bpy.types.Object]
class IfcStore:
path = ""
path: str = ""
file: ifcopenshell.file = None
schema: ifcopenshell.ifcopenshell_wrapper.schema_definition = None
cache: ifcopenshell.ifcopenshell_wrapper.HdfSerializer = None
@@ -44,11 +44,11 @@ class IfcStore:
id_map: dict[int, IFC_CONNECTED_TYPE] = {}
guid_map: dict[str, IFC_CONNECTED_TYPE] = {}
edited_objs: Set[bpy.types.Object] = set()
pset_template_path = ""
pset_template_path: str = ""
pset_template_file: ifcopenshell.file = None
classification_path = ""
classification_path: str = ""
classification_file: ifcopenshell.file = None
library_path = ""
library_path: str = ""
library_file: ifcopenshell.file = None
current_transaction = ""
last_transaction = ""
@@ -280,7 +280,9 @@ class IfcStore:
del IfcStore.guid_map[data["guid"]]
@staticmethod
def unlink_element(element: ifcopenshell.entity_instance = None, obj: IFC_CONNECTED_TYPE = None) -> None:
def unlink_element(
element: Optional[ifcopenshell.entity_instance] = None, obj: Optional[IFC_CONNECTED_TYPE] = None
) -> None:
if element is None:
try:
element = tool.Ifc.get_entity(obj)
+22 -18
View File
@@ -20,45 +20,47 @@ import os
import bpy
import numpy as np
import ifcopenshell.api
import ifcopenshell.util.element
import blenderbim.core.tool
import blenderbim.bim.handler
import blenderbim.tool as tool
from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.ifc import IfcStore, IFC_CONNECTED_TYPE
from typing import Optional, Union, Any
class Ifc(blenderbim.core.tool.Ifc):
@classmethod
def run(cls, command, **kwargs):
def run(cls, command: str, **kwargs) -> Any:
return ifcopenshell.api.run(command, IfcStore.get_file(), **kwargs)
@classmethod
def set(cls, ifc):
def set(cls, ifc: ifcopenshell.file) -> None:
IfcStore.file = ifc
@classmethod
def get(cls):
def get(cls) -> ifcopenshell.file:
return IfcStore.get_file()
@classmethod
def get_path(cls):
def get_path(cls) -> str:
return IfcStore.path
@classmethod
def get_schema(cls):
def get_schema(cls) -> str:
if IfcStore.get_file():
return IfcStore.get_file().schema
@classmethod
def has_changed_shading(cls, obj):
def has_changed_shading(cls, obj: bpy.types.Material) -> bool:
checksum = obj.BIMMaterialProperties.shading_checksum
return checksum != repr(np.array(obj.diffuse_color).tobytes())
@classmethod
def is_edited(cls, obj):
def is_edited(cls, obj: bpy.types.Object) -> bool:
return list(obj.scale) != [1.0, 1.0, 1.0] or obj in IfcStore.edited_objs
@classmethod
def is_moved(cls, obj):
def is_moved(cls, obj: bpy.types.Object) -> bool:
element = cls.get_entity(obj)
if not element or element.is_a("IfcTypeProduct") or element.is_a("IfcProject"):
return False
@@ -77,7 +79,7 @@ class Ifc(blenderbim.core.tool.Ifc):
return IfcStore.get_schema()
@classmethod
def get_entity(cls, obj):
def get_entity(cls, obj: bpy.types.Object) -> ifcopenshell.entity_instance:
ifc = IfcStore.get_file()
props = getattr(obj, "BIMObjectProperties", None)
if ifc and props and props.ifc_definition_id:
@@ -87,7 +89,7 @@ class Ifc(blenderbim.core.tool.Ifc):
pass
@classmethod
def get_entity_by_id(cls, entity_id):
def get_entity_by_id(cls, entity_id) -> Union[ifcopenshell.entity_instance, None]:
"""useful to check whether entity_id is still exists in IFC"""
ifc_file = tool.Ifc.get()
try:
@@ -96,11 +98,11 @@ class Ifc(blenderbim.core.tool.Ifc):
return None
@classmethod
def get_object(cls, element):
def get_object(cls, element: ifcopenshell.entity_instance) -> IFC_CONNECTED_TYPE:
return IfcStore.get_element(element.id())
@classmethod
def rebuild_element_maps(cls):
def rebuild_element_maps(cls) -> None:
"""Rebuilds the id_map and guid_map
When any Blender object is stored outside a Blender PointerProperty,
@@ -153,15 +155,15 @@ class Ifc(blenderbim.core.tool.Ifc):
blenderbim.bim.handler.subscribe_to(obj, "diffuse_color", blenderbim.bim.handler.color_callback)
@classmethod
def link(cls, element, obj):
def link(cls, element: ifcopenshell.entity_instance, obj: IFC_CONNECTED_TYPE) -> None:
IfcStore.link_element(element, obj)
@classmethod
def edit(cls, obj):
def edit(cls, obj: bpy.types.Object) -> None:
IfcStore.edited_objs.add(obj)
@classmethod
def finish_edit(cls, obj):
def finish_edit(cls, obj: bpy.types.Object) -> None:
try:
IfcStore.edited_objs.remove(obj)
except:
@@ -186,11 +188,13 @@ class Ifc(blenderbim.core.tool.Ifc):
return os.path.relpath(uri, ifc_path).replace("\\", "/")
@classmethod
def unlink(cls, element=None, obj=None):
def unlink(
cls, element: Optional[ifcopenshell.entity_instance] = None, obj: Optional[IFC_CONNECTED_TYPE] = None
) -> None:
IfcStore.unlink_element(element, obj)
@classmethod
def get_all_element_occurrences(cls, element):
def get_all_element_occurrences(cls, element: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
if element.is_a("IfcElementType"):
element_type = element
occurrences = ifcopenshell.util.element.get_types(element_type)
@@ -23,13 +23,14 @@ import numpy
import importlib
import ifcopenshell
import ifcopenshell.api
from typing import Callable, Any
pre_listeners = {}
post_listeners = {}
def run(usecase_path, ifc_file=None, should_run_listeners=True, **settings):
def run(usecase_path: str, ifc_file: ifcopenshell.file = None, should_run_listeners=True, **settings) -> Any:
if should_run_listeners:
for listener in pre_listeners.get(usecase_path, {}).values():
listener(usecase_path, ifc_file, settings)
@@ -74,42 +75,44 @@ def run(usecase_path, ifc_file=None, should_run_listeners=True, **settings):
return result
def add_pre_listener(usecase_path, name, callback):
def add_pre_listener(usecase_path: str, name: str, callback: Callable[[str, ifcopenshell.file, dict], None]) -> None:
"""Add a pre listener
:param usecase_path: string, ifcopenshell api use case path
:param name: string, name of listener
:param callback: callback function
:param callback: callback function with 3 arguments: `usecase_path`, `ifc_file`, `settings`
"""
pre_listeners.setdefault(usecase_path, {})[name] = callback
def add_post_listener(usecase_path, name, callback):
def add_post_listener(usecase_path: str, name: str, callback: Callable[[str, ifcopenshell.file, dict], None]) -> None:
"""Add a post listener
:param usecase_path: string, ifcopenshell api use case path
:param name: string, name of listener
:param callback: callback function
:param callback: callback function with 3 arguments: `usecase_path`, `ifc_file`, `settings`
"""
post_listeners.setdefault(usecase_path, {})[name] = callback
def remove_pre_listener(usecase_path, name, callback):
def remove_pre_listener(usecase_path: str, name: str, callback: Callable[[str, ifcopenshell.file, dict], None]) -> None:
"""Remove a pre listener
:param usecase_path: string, ifcopenshell api use case path
:param name: string, name of listener
:param callback: callback function
:param callback: callback function with 3 arguments: `usecase_path`, `ifc_file`, `settings`
"""
pre_listeners.get(usecase_path, {}).pop(name, None)
def remove_post_listener(usecase_path, name, callback):
def remove_post_listener(
usecase_path: str, name: str, callback: Callable[[str, ifcopenshell.file, dict], None]
) -> None:
"""Remove a post listener
:param usecase_path: string, ifcopenshell api use case path
:param name: string, name of listener
:param callback: callback function
:param callback: callback function with 3 arguments: `usecase_path`, `ifc_file`, `settings`
"""
post_listeners.get(usecase_path, {}).pop(name, None)