mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
typing
This commit is contained in:
@@ -277,10 +277,10 @@ def get_user(ifc: ifcopenshell.file) -> Union[ifcopenshell.entity_instance, None
|
||||
return pao
|
||||
elif ifc.schema == "IFC2X3":
|
||||
if (person := next(iter(ifc.by_type("IfcPerson")), None)) is None:
|
||||
person = tool.Ifc.run("owner.add_person")
|
||||
person = ifcopenshell.api.owner.add_person(ifc)
|
||||
if (organization := next(iter(ifc.by_type("IfcOrganization")), None)) is None:
|
||||
organization = tool.Ifc.run("owner.add_organisation")
|
||||
pao = tool.Ifc.run("owner.add_person_and_organisation", person=person, organisation=organization)
|
||||
organization = ifcopenshell.api.owner.add_organisation(ifc)
|
||||
pao = ifcopenshell.api.owner.add_person_and_organisation(ifc, person=person, organisation=organization)
|
||||
return pao
|
||||
|
||||
|
||||
|
||||
@@ -121,7 +121,8 @@ def import_attributes(
|
||||
callback: Optional[ImportCallback] = None,
|
||||
) -> None:
|
||||
schema = tool.Ifc.schema()
|
||||
for attribute in schema.declaration_by_name(ifc_class).all_attributes():
|
||||
assert (entity := schema.declaration_by_name(ifc_class).as_entity())
|
||||
for attribute in entity.all_attributes():
|
||||
import_attribute(attribute, props, data, callback=callback)
|
||||
|
||||
|
||||
@@ -132,11 +133,13 @@ def import_attributes2(
|
||||
callback: Optional[ImportCallback] = None,
|
||||
) -> None:
|
||||
if isinstance(element, str):
|
||||
attributes = tool.Ifc.schema().declaration_by_name(element).as_entity().all_attributes()
|
||||
assert (entity := tool.Ifc.schema().declaration_by_name(element).as_entity())
|
||||
attributes = entity.all_attributes()
|
||||
info = {a.name(): None for a in attributes}
|
||||
info["type"] = element
|
||||
else:
|
||||
attributes = element.wrapped_data.declaration().as_entity().all_attributes()
|
||||
assert (entity := element.wrapped_data.declaration().as_entity())
|
||||
attributes = entity.all_attributes()
|
||||
info = element.get_info()
|
||||
for attribute in attributes:
|
||||
import_attribute(attribute, props, info, callback=callback)
|
||||
|
||||
@@ -42,7 +42,10 @@ from bpy_extras.io_utils import ImportHelper, ExportHelper
|
||||
from pathlib import Path
|
||||
from bonsai import get_debug_info, format_debug_info
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
from typing import get_args, Union
|
||||
from typing import get_args, Union, Any, TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.prop import Attribute
|
||||
|
||||
|
||||
class CopyDebugInformation(bpy.types.Operator):
|
||||
@@ -70,6 +73,7 @@ class CopyDebugInformation(bpy.types.Operator):
|
||||
print(text_with_backticks)
|
||||
print("-" * 80)
|
||||
|
||||
assert context.window_manager
|
||||
context.window_manager.clipboard = text_with_backticks
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -347,8 +351,9 @@ class SelectHighPolygonMeshes(bpy.types.Operator):
|
||||
threshold: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
assert context.view_layer
|
||||
for obj in context.view_layer.objects:
|
||||
if obj.type == "MESH" and len(obj.data.polygons) > self.threshold:
|
||||
if isinstance(obj.data, bpy.types.Mesh) and len(obj.data.polygons) > self.threshold:
|
||||
obj.select_set(True)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -361,6 +366,7 @@ class SelectHighestPolygonMeshes(bpy.types.Operator):
|
||||
percentile: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
assert context.view_layer
|
||||
objects = [obj for obj in context.view_layer.objects if obj.type == "MESH"]
|
||||
if objects:
|
||||
percentile = len(max(objects, key=lambda o: len(o.data.polygons)).data.polygons) * self.percentile / 100
|
||||
@@ -423,7 +429,7 @@ class InspectFromStepId(bpy.types.Operator):
|
||||
new.int_value = inverse.id()
|
||||
return {"FINISHED"}
|
||||
|
||||
def add_attribute(self, prop, key, value):
|
||||
def add_attribute(self, prop: "bpy.types.bpy_prop_collection_idprop[Attribute]", key: str, value: Any) -> None:
|
||||
if isinstance(value, tuple) and len(value) < 10:
|
||||
for i, item in enumerate(value):
|
||||
self.add_attribute(prop, key + f"[{i}]", item)
|
||||
@@ -459,8 +465,10 @@ class InspectFromObject(bpy.types.Operator):
|
||||
def poll(cls, context):
|
||||
if not context.active_object:
|
||||
cls.poll_message_set("No Active Object")
|
||||
return False
|
||||
elif not cls.get_active_object_ifc_definition(context):
|
||||
cls.poll_message_set("Active Object doesn't have an IFC definition")
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
@@ -492,6 +500,7 @@ class PrintObjectPlacement(bpy.types.Operator):
|
||||
if self.create_empty_object:
|
||||
bpy.ops.object.empty_add(type="ARROWS")
|
||||
si_conversion = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||
assert context.active_object
|
||||
context.active_object.matrix_world = placement.transpose()
|
||||
context.active_object.matrix_world.translation *= si_conversion
|
||||
context.active_object.empty_display_size = self.arrow_size
|
||||
@@ -1017,6 +1026,7 @@ class RestartBlender(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
# Save preferences manually since we're restarting Blender using .execv
|
||||
# and it doens't have a chance to save them on exit.
|
||||
assert context.preferences
|
||||
if context.preferences.use_preferences_save:
|
||||
bpy.ops.wm.save_userpref()
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ class BIM_PT_debug(Panel):
|
||||
bl_parent_id = "BIM_PT_tab_quality_control"
|
||||
|
||||
def draw(self, context):
|
||||
assert self.layout
|
||||
layout = self.layout
|
||||
|
||||
props = tool.Debug.get_debug_props()
|
||||
|
||||
@@ -26,15 +26,15 @@ if TYPE_CHECKING:
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
def parse_express(debug: tool.Debug, filename: str) -> None:
|
||||
def parse_express(debug: type[tool.Debug], filename: str) -> None:
|
||||
debug.add_schema_identifier(debug.load_express(filename))
|
||||
|
||||
|
||||
def purge_hdf5_cache(debug: tool.Debug) -> None:
|
||||
def purge_hdf5_cache(debug: type[tool.Debug]) -> None:
|
||||
debug.purge_hdf5_cache()
|
||||
|
||||
|
||||
def purge_unused_elements(ifc, debug: tool.Debug, ifc_class: str) -> int:
|
||||
def purge_unused_elements(ifc: type[tool.Ifc], debug: type[tool.Debug], ifc_class: str) -> int:
|
||||
ifc_file = ifc.get()
|
||||
unused_elements = [i for i in ifc_file.by_type(ifc_class) if ifc_file.get_total_inverses(i) == 0]
|
||||
unused_elements_amount = len(unused_elements)
|
||||
|
||||
@@ -25,7 +25,7 @@ if TYPE_CHECKING:
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
def purge_unused_profiles(ifc: tool.Ifc, profile: tool.Profile) -> int:
|
||||
def purge_unused_profiles(ifc: type[tool.Ifc], profile: type[tool.Profile]) -> int:
|
||||
"""Purge profiles that have no inverses.
|
||||
|
||||
:return: Number of removed profiles.
|
||||
|
||||
@@ -25,7 +25,7 @@ if TYPE_CHECKING:
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
def add_style(ifc: tool.Ifc, style: tool.Style, obj: bpy.types.Material) -> ifcopenshell.entity_instance:
|
||||
def add_style(ifc: type[tool.Ifc], style: type[tool.Style], obj: bpy.types.Material) -> ifcopenshell.entity_instance:
|
||||
element = ifc.run("style.add_style", name=style.get_name(obj))
|
||||
ifc.link(element, obj)
|
||||
if style.can_support_rendering_style(obj):
|
||||
@@ -38,7 +38,9 @@ def add_style(ifc: tool.Ifc, style: tool.Style, obj: bpy.types.Material) -> ifco
|
||||
|
||||
|
||||
# TODO: outdated.
|
||||
def add_external_style(ifc: tool.Ifc, style: tool.Style, obj: bpy.types.Material, attributes: dict[str, Any]) -> None:
|
||||
def add_external_style(
|
||||
ifc: type[tool.Ifc], style: type[tool.Style], obj: bpy.types.Material, attributes: dict[str, Any]
|
||||
) -> None:
|
||||
element = ifc.get_entity(obj)
|
||||
ifc.run(
|
||||
"style.add_surface_style", style=element, ifc_class="IfcExternallyDefinedSurfaceStyle", attributes=attributes
|
||||
@@ -47,7 +49,7 @@ def add_external_style(ifc: tool.Ifc, style: tool.Style, obj: bpy.types.Material
|
||||
|
||||
# TODO: unused `style` argument?
|
||||
def update_external_style(
|
||||
ifc: tool.Ifc,
|
||||
ifc: type[tool.Ifc],
|
||||
style: ifcopenshell.entity_instance,
|
||||
external_style: ifcopenshell.entity_instance,
|
||||
attributes: dict[str, Any],
|
||||
@@ -56,7 +58,10 @@ def update_external_style(
|
||||
|
||||
|
||||
def remove_style(
|
||||
ifc: tool.Ifc, style_tool: tool.Style, style: ifcopenshell.entity_instance, reload_styles_ui: bool = False
|
||||
ifc: type[tool.Ifc],
|
||||
style_tool: type[tool.Style],
|
||||
style: ifcopenshell.entity_instance,
|
||||
reload_styles_ui: bool = False,
|
||||
) -> None:
|
||||
"""Remove IfcPresentationStyle and associated Blender material.
|
||||
|
||||
@@ -78,7 +83,9 @@ def remove_style(
|
||||
style_tool.import_presentation_styles(style_type)
|
||||
|
||||
|
||||
def update_style_colours(ifc: tool.Ifc, style: tool.Style, obj: bpy.types.Material, verbose: bool = False) -> None:
|
||||
def update_style_colours(
|
||||
ifc: type[tool.Ifc], style: type[tool.Style], obj: bpy.types.Material, verbose: bool = False
|
||||
) -> None:
|
||||
element = ifc.get_entity(obj)
|
||||
|
||||
if style.can_support_rendering_style(obj):
|
||||
@@ -114,7 +121,10 @@ def update_style_colours(ifc: tool.Ifc, style: tool.Style, obj: bpy.types.Materi
|
||||
|
||||
|
||||
def update_style_textures(
|
||||
ifc: tool.Ifc, style: tool.Style, obj: ifcopenshell.entity_instance, representation: ifcopenshell.entity_instance
|
||||
ifc: type[tool.Ifc],
|
||||
style: type[tool.Style],
|
||||
obj: ifcopenshell.entity_instance,
|
||||
representation: ifcopenshell.entity_instance,
|
||||
) -> None:
|
||||
element = ifc.get_entity(obj)
|
||||
|
||||
@@ -136,22 +146,22 @@ def update_style_textures(
|
||||
|
||||
|
||||
# TODO: outdated.
|
||||
def unlink_style(ifc: tool.Ifc, style: ifcopenshell.entity_instance) -> None:
|
||||
def unlink_style(ifc: type[tool.Ifc], style: ifcopenshell.entity_instance) -> None:
|
||||
ifc.unlink(element=style)
|
||||
|
||||
|
||||
def enable_editing_style(style_tool: tool.Style, style: ifcopenshell.entity_instance) -> None:
|
||||
def enable_editing_style(style_tool: type[tool.Style], style: ifcopenshell.entity_instance) -> None:
|
||||
style_tool.enable_editing(style)
|
||||
style_tool.import_surface_attributes(style)
|
||||
|
||||
|
||||
def disable_editing_style(style: tool.Style) -> None:
|
||||
def disable_editing_style(style: type[tool.Style]) -> None:
|
||||
obj = style.get_currently_edited_material()
|
||||
style.disable_editing()
|
||||
style.reload_material_from_ifc(obj)
|
||||
|
||||
|
||||
def edit_style(ifc: tool.Ifc, style: tool.Style) -> None:
|
||||
def edit_style(ifc: type[tool.Ifc], style: type[tool.Style]) -> None:
|
||||
obj = style.get_currently_edited_material()
|
||||
style_element = ifc.get_entity(obj)
|
||||
assert style_element
|
||||
@@ -164,14 +174,16 @@ def edit_style(ifc: tool.Ifc, style: tool.Style) -> None:
|
||||
style.reload_representations(style_element)
|
||||
|
||||
|
||||
def load_styles(style: tool.Style, style_type: str) -> None:
|
||||
def load_styles(style: type[tool.Style], style_type: str) -> None:
|
||||
style.import_presentation_styles(style_type)
|
||||
style.enable_editing_styles()
|
||||
|
||||
|
||||
def disable_editing_styles(style: tool.Style) -> None:
|
||||
def disable_editing_styles(style: type[tool.Style]) -> None:
|
||||
style.disable_editing_styles()
|
||||
|
||||
|
||||
def select_by_style(style_tool: tool.Style, spatial: tool.Spatial, style: ifcopenshell.entity_instance) -> None:
|
||||
def select_by_style(
|
||||
style_tool: type[tool.Style], spatial: type[tool.Spatial], style: ifcopenshell.entity_instance
|
||||
) -> None:
|
||||
spatial.select_products(style_tool.get_elements_by_style(style))
|
||||
|
||||
@@ -27,7 +27,10 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
def assign_type(
|
||||
ifc: tool.Ifc, type_tool: tool.Type, element: ifcopenshell.entity_instance, type: ifcopenshell.entity_instance
|
||||
ifc: type[tool.Ifc],
|
||||
type_tool: type[tool.Type],
|
||||
element: ifcopenshell.entity_instance,
|
||||
type: ifcopenshell.entity_instance,
|
||||
) -> None:
|
||||
ifc.run("type.assign_type", related_objects=[element], relating_type=type)
|
||||
obj = ifc.get_object(element)
|
||||
@@ -40,7 +43,7 @@ def assign_type(
|
||||
type_tool.disable_editing(obj)
|
||||
|
||||
|
||||
def purge_unused_types(ifc: tool.Ifc, type: tool.Type, geometry: tool.Geometry) -> int:
|
||||
def purge_unused_types(ifc: type[tool.Ifc], type: type[tool.Type], geometry: type[tool.Geometry]) -> int:
|
||||
"""Remove all types without occurrences, return an amount of the removed types."""
|
||||
purged_types = 0
|
||||
for element_type in type.get_model_types():
|
||||
|
||||
@@ -26,7 +26,7 @@ import operator
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
from typing import Union, Any, TypeVar, overload, TYPE_CHECKING
|
||||
from typing import Union, Any, TypeVar, overload, TYPE_CHECKING, cast, NoReturn
|
||||
from collections.abc import Callable, Sequence
|
||||
|
||||
from . import ifcopenshell_wrapper
|
||||
@@ -64,17 +64,20 @@ def set_unsupported_attribute(*args):
|
||||
# done for each invocation of __setitem__. Now this
|
||||
# mapping is built once during initialization of the
|
||||
# module.
|
||||
_method_dict = {}
|
||||
MethodList = list[Callable[[ifcopenshell_wrapper.entity_instance, int, Any], Union[None, NoReturn]]]
|
||||
"""List of setter methods for class attributes."""
|
||||
_method_dict: dict[str, MethodList] = {}
|
||||
"""Mapping of entity classes (e.g. 'IFC4.IfcWall') to MethodLists."""
|
||||
|
||||
|
||||
def register_schema_attributes(schema: ifcopenshell_wrapper.schema_definition) -> None:
|
||||
for decl in schema.declarations():
|
||||
decl: ifcopenshell_wrapper.declaration
|
||||
if hasattr(decl, "argument_types"):
|
||||
fq_name = ".".join((schema.name(), decl.name()))
|
||||
|
||||
# get type strings as reported by IfcOpenShell C++
|
||||
type_strs = decl.argument_types()
|
||||
type_strs = cast(Sequence[str], type_strs)
|
||||
|
||||
# convert case for setter function
|
||||
type_strs = [x.title().replace(" ", "") for x in type_strs]
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
from typing import Any, Union, Literal
|
||||
|
||||
# `std::vector<xxx>` usually translated to `tuple[xxx, ...]`.
|
||||
@@ -775,6 +776,9 @@ class entity(declaration):
|
||||
def supertype(self) -> Union[entity, None]: ...
|
||||
|
||||
class entity_instance:
|
||||
file: ifcopenshell.file
|
||||
"""Reference to IFC file to prevent it's garbage collection, if entity is still used."""
|
||||
|
||||
file_: Any
|
||||
id_: Any
|
||||
def data(self, *args): ...
|
||||
|
||||
@@ -282,9 +282,10 @@ def get_cost_values(cost_item: ifcopenshell.entity_instance) -> list[dict[str, s
|
||||
|
||||
|
||||
def get_cost_schedule_types(file: ifcopenshell.file) -> list[dict[str, str]]:
|
||||
schema: ifcopenshell_wrapper.schema_definition = ifcopenshell_wrapper.schema_by_name(file.schema_identifier)
|
||||
schema = ifcopenshell_wrapper.schema_by_name(file.schema_identifier)
|
||||
results = []
|
||||
declaration = schema.declaration_by_name("IfcCostSchedule")
|
||||
declaration = schema.declaration_by_name("IfcCostSchedule").as_entity()
|
||||
assert declaration
|
||||
version = file.schema_identifier
|
||||
for attribute in declaration.attributes():
|
||||
if attribute.name() == "PredefinedType":
|
||||
|
||||
@@ -136,8 +136,8 @@ def get_subtypes(
|
||||
[<entity IfcFlowSegment>, <entity IfcCableCarrierSegment>, ..., <entity IfcPipeSegment>]
|
||||
"""
|
||||
|
||||
def get_classes(decl):
|
||||
results = []
|
||||
def get_classes(decl: ifcopenshell_wrapper.entity) -> list[ifcopenshell_wrapper.entity]:
|
||||
results: list[ifcopenshell_wrapper.entity] = []
|
||||
if not decl.is_abstract():
|
||||
results.append(decl)
|
||||
for subtype in decl.subtypes():
|
||||
@@ -172,7 +172,7 @@ def reassign_class(
|
||||
if not ifc_file:
|
||||
ifc_file = element.file
|
||||
|
||||
schema: ifcopenshell_wrapper.schema_definition = ifcopenshell_wrapper.schema_by_name(ifc_file.schema_identifier)
|
||||
schema = ifcopenshell_wrapper.schema_by_name(ifc_file.schema_identifier)
|
||||
try:
|
||||
declaration = schema.declaration_by_name(new_class)
|
||||
except RuntimeError:
|
||||
|
||||
@@ -815,12 +815,13 @@ def iter_element_and_attributes_per_type(ifc_file: ifcopenshell.file, attr_type_
|
||||
None,
|
||||
None,
|
||||
]:
|
||||
schema: ifcopenshell_wrapper.schema_definition = ifcopenshell_wrapper.schema_by_name(ifc_file.schema_identifier)
|
||||
schema = ifcopenshell_wrapper.schema_by_name(ifc_file.schema_identifier)
|
||||
|
||||
for element in ifc_file:
|
||||
entity = schema.declaration_by_name(element.is_a())
|
||||
entity = schema.declaration_by_name(element.is_a()).as_entity()
|
||||
assert entity
|
||||
attrs = entity.all_attributes()
|
||||
attrs_derived: tuple[bool, ...] = entity.derived()
|
||||
attrs_derived = entity.derived()
|
||||
for attr, val, is_derived in zip(attrs, list(element), attrs_derived):
|
||||
if is_derived:
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user