diff --git a/src/blenderbim/blenderbim/bim/module/cost/data.py b/src/blenderbim/blenderbim/bim/module/cost/data.py
index 1c424cb1d6..09698a54be 100644
--- a/src/blenderbim/blenderbim/bim/module/cost/data.py
+++ b/src/blenderbim/blenderbim/bim/module/cost/data.py
@@ -198,8 +198,11 @@ class CostSchedulesData:
# data["DerivedUnitSymbol"] = "?"
# print("Total Cost", data["DerivedTotalCostQuantity"], cost_item.Name)
+ # TODO: dead code?
@classmethod
- def _get_object_quantities(cls, cost_item, element):
+ def _get_object_quantities(
+ cls, cost_item: ifcopenshell.entity_instance, element: ifcopenshell.entity_instance
+ ) -> list[int]:
if not element.is_a("IfcObject"):
return []
cost_quantities = cost_item.CostQuantities
diff --git a/src/blenderbim/blenderbim/bim/module/geometry/operator.py b/src/blenderbim/blenderbim/bim/module/geometry/operator.py
index a26831bff1..385ca383c9 100644
--- a/src/blenderbim/blenderbim/bim/module/geometry/operator.py
+++ b/src/blenderbim/blenderbim/bim/module/geometry/operator.py
@@ -28,6 +28,7 @@ import ifcopenshell.util.element
import ifcopenshell.util.representation
import ifcopenshell.util.placement
import ifcopenshell.api
+import blenderbim.core.geometry
import blenderbim.core.geometry as core
import blenderbim.core.aggregate
import blenderbim.core.style
diff --git a/src/blenderbim/blenderbim/bim/module/style/operator.py b/src/blenderbim/blenderbim/bim/module/style/operator.py
index e8b0479f9c..cf36eee95e 100644
--- a/src/blenderbim/blenderbim/bim/module/style/operator.py
+++ b/src/blenderbim/blenderbim/bim/module/style/operator.py
@@ -22,6 +22,7 @@ import blenderbim.bim.helper
import blenderbim.bim.handler
import blenderbim.tool as tool
import blenderbim.core.style as core
+import ifcopenshell.api
import ifcopenshell.util.representation
from blenderbim.bim.module.style.prop import switch_shading
from pathlib import Path
diff --git a/src/blenderbim/blenderbim/core/aggregate.py b/src/blenderbim/blenderbim/core/aggregate.py
index 58d10814a7..44d4444f79 100644
--- a/src/blenderbim/blenderbim/core/aggregate.py
+++ b/src/blenderbim/blenderbim/core/aggregate.py
@@ -16,16 +16,30 @@
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see .
+from __future__ import annotations
+from typing import TYPE_CHECKING, Optional, Union
-def enable_editing_aggregate(aggregator, obj=None):
+if TYPE_CHECKING:
+ import bpy
+ import ifcopenshell
+ import blenderbim.tool as tool
+
+
+def enable_editing_aggregate(aggregator: tool.Aggregate, obj: bpy.types.Object) -> None:
aggregator.enable_editing(obj)
-def disable_editing_aggregate(aggregator, obj=None):
+def disable_editing_aggregate(aggregator: tool.Aggregate, obj: bpy.types.Object) -> None:
aggregator.disable_editing(obj)
-def assign_object(ifc, aggregator, collector, relating_obj=None, related_obj=None):
+def assign_object(
+ ifc: tool.Ifc,
+ aggregator: tool.Aggregate,
+ collector: tool.Collector,
+ relating_obj: Optional[bpy.types.Object] = None,
+ related_obj: Optional[bpy.types.Object] = None,
+) -> Union[ifcopenshell.entity_instance, None]:
if not aggregator.can_aggregate(relating_obj, related_obj):
return
rel = ifc.run(
@@ -37,7 +51,13 @@ def assign_object(ifc, aggregator, collector, relating_obj=None, related_obj=Non
return rel
-def unassign_object(ifc, aggregate, collector, relating_obj=None, related_obj=None):
+def unassign_object(
+ ifc: tool.Ifc,
+ aggregate: tool.Aggregate,
+ collector: tool.Collector,
+ relating_obj: Optional[bpy.types.Object] = None,
+ related_obj: Optional[bpy.types.Object] = None,
+) -> None:
related_element = ifc.get_entity(related_obj)
container = aggregate.get_container(related_element)
if not relating_obj:
@@ -52,7 +72,15 @@ def unassign_object(ifc, aggregate, collector, relating_obj=None, related_obj=No
collector.assign(related_obj)
-def add_part_to_object(ifc, aggregator, collector, blender, obj, part_class, part_name=None):
+def add_part_to_object(
+ ifc: tool.Ifc,
+ aggregator: tool.Aggregate,
+ collector: tool.Collector,
+ blender: tool.Blender,
+ obj: bpy.types.Object,
+ part_class: str,
+ part_name: Optional[str] = None,
+) -> None:
part_obj = blender.create_ifc_object(ifc_class=part_class, name=part_name)
assign_object(ifc, aggregator, collector, relating_obj=obj, related_obj=part_obj)
blender.set_active_object(obj)
diff --git a/src/blenderbim/blenderbim/core/material.py b/src/blenderbim/blenderbim/core/material.py
index bd3eb87748..5a33704ead 100644
--- a/src/blenderbim/blenderbim/core/material.py
+++ b/src/blenderbim/blenderbim/core/material.py
@@ -16,15 +16,33 @@
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see .
+from __future__ import annotations
+from typing import TYPE_CHECKING, Optional, Union
-def unlink_material(ifc, obj=None):
+if TYPE_CHECKING:
+ import bpy
+ import ifcopenshell
+ import blenderbim.tool as tool
+
+
+def unlink_material(ifc: tool.Ifc, obj: bpy.types.Material) -> None:
ifc.unlink(obj=obj)
-def add_material(ifc, material, style, obj=None, name=None, category=None, description=None):
+def add_material(
+ ifc: tool.Ifc,
+ material: tool.Material,
+ style: tool.Style,
+ obj: Optional[bpy.types.Material] = None,
+ name: Optional[str] = None,
+ category: Optional[str] = None,
+ description: Optional[str] = None,
+) -> ifcopenshell.entity_instance:
if not obj:
obj = material.add_default_material_object(name)
- ifc_material = ifc.run("material.add_material", name=material.get_name(obj), category=category, description=description)
+ ifc_material = ifc.run(
+ "material.add_material", name=material.get_name(obj), category=category, description=description
+ )
ifc.link(ifc_material, obj)
ifc_style = style.get_style(obj)
if ifc_style:
@@ -36,14 +54,16 @@ def add_material(ifc, material, style, obj=None, name=None, category=None, descr
return ifc_material
-def add_material_set(ifc, material, set_type=None):
+def add_material_set(ifc: tool.Ifc, material: tool.Material, set_type: str) -> ifcopenshell.entity_instance:
ifc_material = ifc.run("material.add_material_set", name="Unnamed", set_type=set_type)
if material.is_editing_materials():
material.import_material_definitions(material.get_active_material_type())
return ifc_material
-def remove_material(ifc, material_tool, style, material=None) -> bool:
+def remove_material(
+ ifc: tool.Ifc, material_tool: tool.Material, style: tool.Style, material: ifcopenshell.entity_instance
+) -> bool:
"""returns True after deleting False,\n
returns False if material used in material sets and cannot be removed"""
if material_tool.is_material_used_in_sets(material):
@@ -58,31 +78,33 @@ def remove_material(ifc, material_tool, style, material=None) -> bool:
return True
-def remove_material_set(ifc, material_tool, material=None):
+def remove_material_set(ifc: tool.Ifc, material_tool: tool.Material, material: ifcopenshell.entity_instance) -> None:
ifc.run("material.remove_material_set", material=material)
if material_tool.is_editing_materials():
material_tool.import_material_definitions(material_tool.get_active_material_type())
-def load_materials(material, material_type=None):
+def load_materials(material: tool.Material, material_type: str) -> None:
material.import_material_definitions(material_type)
material.enable_editing_materials()
-def disable_editing_materials(material):
+def disable_editing_materials(material: tool.Material) -> None:
material.disable_editing_materials()
-def select_by_material(material_tool, spatial, material=None):
+def select_by_material(
+ material_tool: tool.Material, spatial: tool.Spatial, material: ifcopenshell.entity_instance
+) -> None:
spatial.select_products(material_tool.get_elements_by_material(material))
-def enable_editing_material(material_tool, material):
+def enable_editing_material(material_tool: tool.Material, material: ifcopenshell.entity_instance) -> None:
material_tool.load_material_attributes(material)
material_tool.enable_editing_material(material)
-def edit_material(ifc, material_tool, material):
+def edit_material(ifc: tool.Ifc, material_tool: tool.Material, material: ifcopenshell.entity_instance) -> None:
attributes = material_tool.get_material_attributes()
ifc.run("material.edit_material", material=material, attributes=attributes)
material_tool.sync_blender_material_name(material)
@@ -92,11 +114,13 @@ def edit_material(ifc, material_tool, material):
material_tool.enable_editing_materials()
-def disable_editing_material(material_tool):
+def disable_editing_material(material_tool: tool.Material) -> None:
material_tool.disable_editing_material()
-def assign_material(ifc, material_tool, material_type, objects):
+def assign_material(
+ ifc: tool.Ifc, material_tool: tool.Material, material_type: Union[str, None], objects: list[bpy.types.Object]
+) -> None:
material_type = material_type or material_tool.get_active_object_material()
material = material_tool.get_active_material()
for obj in objects:
@@ -109,7 +133,7 @@ def assign_material(ifc, material_tool, material_type, objects):
material_tool.add_material_to_set(material_set=assigned_material, material=material)
-def unassign_material(ifc, material_tool, objects):
+def unassign_material(ifc: tool.Ifc, material_tool: tool.Material, objects: list[bpy.types.Object]) -> None:
for obj in objects:
element = ifc.get_entity(obj)
if element:
@@ -125,7 +149,9 @@ def unassign_material(ifc, material_tool, objects):
ifc.run("material.unassign_material", products=[element])
-def patch_non_parametric_mep_segment(ifc, material_tool, profile_tool, obj):
+def patch_non_parametric_mep_segment(
+ ifc: tool.Ifc, material_tool: tool.Material, profile_tool: tool.Profile, obj: bpy.types.Object
+) -> None:
element = ifc.get_entity(obj)
if not element:
return
diff --git a/src/blenderbim/blenderbim/core/style.py b/src/blenderbim/blenderbim/core/style.py
index 13576cb80f..f22b4b15d9 100644
--- a/src/blenderbim/blenderbim/core/style.py
+++ b/src/blenderbim/blenderbim/core/style.py
@@ -16,8 +16,16 @@
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see .
+from __future__ import annotations
+from typing import TYPE_CHECKING, Optional, Any
-def add_style(ifc, style, obj=None):
+if TYPE_CHECKING:
+ import bpy
+ import ifcopenshell
+ import blenderbim.tool as tool
+
+
+def add_style(ifc: tool.Ifc, style: 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):
@@ -33,18 +41,26 @@ def add_style(ifc, style, obj=None):
return element
-def add_external_style(ifc, style, obj, attributes):
+def add_external_style(ifc: tool.Ifc, style: tool.Style, obj: bpy.types.Material, attributes: dict[str, Any]) -> None:
element = style.get_style(obj)
ifc.run(
"style.add_surface_style", style=element, ifc_class="IfcExternallyDefinedSurfaceStyle", attributes=attributes
)
-def update_external_style(ifc, style, external_style, attributes):
+# TODO: unused `style` argument?
+def update_external_style(
+ ifc: tool.Ifc,
+ style: ifcopenshell.entity_instance,
+ external_style: ifcopenshell.entity_instance,
+ attributes: dict[str, Any],
+) -> None:
ifc.run("style.edit_surface_style", style=external_style, attributes=attributes)
-def remove_style(ifc, material, style_tool, style=None):
+def remove_style(
+ ifc: tool.Ifc, material: tool.Material, style_tool: tool.Style, style: ifcopenshell.entity_instance
+) -> None:
obj = ifc.get_object(style)
ifc.unlink(obj=obj, element=style)
ifc.run("style.remove_style", style=style)
@@ -54,7 +70,7 @@ def remove_style(ifc, material, style_tool, style=None):
style_tool.import_presentation_styles(style_tool.get_active_style_type())
-def update_style_colours(ifc, style, obj=None, verbose=False):
+def update_style_colours(ifc: tool.Ifc, style: tool.Style, obj: bpy.types.Material, verbose: bool = False) -> None:
element = style.get_style(obj)
if style.can_support_rendering_style(obj):
@@ -91,7 +107,9 @@ def update_style_colours(ifc, style, obj=None, verbose=False):
style.record_shading(obj)
-def update_style_textures(ifc, style, obj=None, representation=None):
+def update_style_textures(
+ ifc: tool.Ifc, style: tool.Style, obj: ifcopenshell.entity_instance, representation: ifcopenshell.entity_instance
+) -> None:
element = style.get_style(obj)
uv_maps = style.get_uv_maps(representation)
@@ -111,34 +129,34 @@ def update_style_textures(ifc, style, obj=None, representation=None):
ifc.run("style.remove_surface_style", style=texture_style)
-def unlink_style(ifc, style=None):
+def unlink_style(ifc: tool.Ifc, style: ifcopenshell.entity_instance) -> None:
obj = ifc.get_object(style)
ifc.unlink(obj=obj, element=style)
-def enable_editing_style(style, obj=None):
+def enable_editing_style(style: tool.Style, obj: bpy.types.Material) -> None:
style.enable_editing(obj)
style.import_surface_attributes(style.get_style(obj), obj)
-def disable_editing_style(style, obj=None):
+def disable_editing_style(style: tool.Style, obj: bpy.types.Material) -> None:
style.disable_editing(obj)
-def edit_style(ifc, style, obj=None):
+def edit_style(ifc: tool.Ifc, style: tool.Style, obj: bpy.types.Material) -> None:
attributes = style.export_surface_attributes(obj)
ifc.run("style.edit_presentation_style", style=style.get_style(obj), attributes=attributes)
style.disable_editing(obj)
-def load_styles(style, style_type=None):
+def load_styles(style: tool.Style, style_type: str) -> None:
style.import_presentation_styles(style_type)
style.enable_editing_styles()
-def disable_editing_styles(style):
+def disable_editing_styles(style: tool.Style) -> None:
style.disable_editing_styles()
-def select_by_style(style_tool, spatial, style=None):
+def select_by_style(style_tool: tool.Style, spatial: tool.Spatial, style: ifcopenshell.entity_instance) -> None:
spatial.select_products(style_tool.get_elements_by_style(style))
diff --git a/src/blenderbim/blenderbim/tool/aggregate.py b/src/blenderbim/blenderbim/tool/aggregate.py
index 66e549f67d..9188e12a32 100644
--- a/src/blenderbim/blenderbim/tool/aggregate.py
+++ b/src/blenderbim/blenderbim/tool/aggregate.py
@@ -20,6 +20,7 @@ import bpy
import blenderbim.core.tool
import blenderbim.tool as tool
import ifcopenshell.util.element
+from typing import Union
class Aggregate(blenderbim.core.tool.Aggregate):
@@ -46,19 +47,21 @@ class Aggregate(blenderbim.core.tool.Aggregate):
return False
@classmethod
- def disable_editing(cls, obj):
+ def disable_editing(cls, obj: bpy.types.Object) -> None:
obj.BIMObjectAggregateProperties.is_editing = False
@classmethod
- def enable_editing(cls, obj):
+ def enable_editing(cls, obj: bpy.types.Object) -> None:
obj.BIMObjectAggregateProperties.is_editing = True
@classmethod
- def get_container(cls, element):
+ def get_container(cls, element: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
return ifcopenshell.util.element.get_container(element)
@classmethod
- def get_relating_object(cls, related_element):
+ def get_relating_object(
+ cls, related_element: ifcopenshell.entity_instance
+ ) -> Union[ifcopenshell.entity_instance, None]:
for rel in related_element.Decomposes:
if rel.is_a("IfcRelAggregates"):
return rel.RelatingObject
diff --git a/src/blenderbim/blenderbim/tool/material.py b/src/blenderbim/blenderbim/tool/material.py
index a1bd4a51b8..4a72301f2f 100644
--- a/src/blenderbim/blenderbim/tool/material.py
+++ b/src/blenderbim/blenderbim/tool/material.py
@@ -19,43 +19,45 @@
import bpy
import ifcopenshell
import blenderbim.core.tool
+import blenderbim.core.material
import blenderbim.tool as tool
import blenderbim.bim.helper
import ifcopenshell.util.unit
import ifcopenshell.util.element
+from typing import Union, Any
class Material(blenderbim.core.tool.Material):
@classmethod
- def add_default_material_object(cls, name):
+ def add_default_material_object(cls, name: Union[str, None]) -> bpy.types.Material:
return bpy.data.materials.new(name or "Default")
@classmethod
- def delete_object(cls, obj):
+ def delete_object(cls, obj: bpy.types.Material) -> None:
bpy.data.materials.remove(obj)
@classmethod
- def disable_editing_materials(cls):
+ def disable_editing_materials(cls) -> None:
bpy.context.scene.BIMMaterialProperties.is_editing = False
@classmethod
- def enable_editing_materials(cls):
+ def enable_editing_materials(cls) -> None:
bpy.context.scene.BIMMaterialProperties.is_editing = True
@classmethod
- def get_active_material_type(cls):
+ def get_active_material_type(cls) -> str:
return bpy.context.scene.BIMMaterialProperties.material_type
@classmethod
- def get_elements_by_material(cls, material):
+ def get_elements_by_material(cls, material: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
return ifcopenshell.util.element.get_elements_by_material(tool.Ifc.get(), material)
@classmethod
- def get_name(cls, obj):
+ def get_name(cls, obj: bpy.types.Material) -> str:
return obj.name
@classmethod
- def import_material_definitions(cls, material_type):
+ def import_material_definitions(cls, material_type: str) -> None:
props = bpy.context.scene.BIMMaterialProperties
expanded_categories = {m.name for m in props.materials if m.is_expanded}
props.materials.clear()
@@ -89,11 +91,11 @@ class Material(blenderbim.core.tool.Material):
new.total_elements = len(ifcopenshell.util.element.get_elements_by_material(tool.Ifc.get(), material))
@classmethod
- def is_editing_materials(cls):
+ def is_editing_materials(cls) -> bool:
return bpy.context.scene.BIMMaterialProperties.is_editing
@classmethod
- def is_material_used_in_sets(cls, material):
+ def is_material_used_in_sets(cls, material: ifcopenshell.entity_instance) -> bool:
for inverse in tool.Ifc.get().get_inverse(material):
if inverse.is_a() in [
"IfcMaterialProfile",
@@ -105,48 +107,50 @@ class Material(blenderbim.core.tool.Material):
return False
@classmethod
- def load_material_attributes(cls, material):
+ def load_material_attributes(cls, material: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMMaterialProperties
props.material_attributes.clear()
blenderbim.bim.helper.import_attributes2(material, props.material_attributes)
@classmethod
- def enable_editing_material(cls, material):
+ def enable_editing_material(cls, material: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMMaterialProperties
props.active_material_id = material.id()
props.editing_material_type = "ATTRIBUTES"
@classmethod
- def get_material_attributes(cls):
+ def get_material_attributes(cls) -> dict[str, Any]:
return blenderbim.bim.helper.export_attributes(bpy.context.scene.BIMMaterialProperties.material_attributes)
@classmethod
- def disable_editing_material(cls):
+ def disable_editing_material(cls) -> None:
props = bpy.context.scene.BIMMaterialProperties
props.active_material_id = 0
props.editing_material_type = ""
@classmethod
- def get_type(cls, element):
+ def get_type(cls, element: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
return ifcopenshell.util.element.get_type(element)
@classmethod
- def get_active_object_material(cls):
+ def get_active_object_material(cls) -> Union[str, None]:
active_obj = bpy.context.active_object
if not active_obj:
return
return active_obj.BIMObjectMaterialProperties.material_type
@classmethod
- def get_active_material(cls):
+ def get_active_material(cls) -> ifcopenshell.entity_instance:
return tool.Ifc.get().by_id(int(bpy.context.active_object.BIMObjectMaterialProperties.material))
@classmethod
- def get_material(cls, element, should_inherit=False):
+ def get_material(
+ cls, element: ifcopenshell.entity_instance, should_inherit: bool = False
+ ) -> Union[ifcopenshell.entity_instance, None]:
return ifcopenshell.util.element.get_material(element, should_inherit=should_inherit)
@classmethod
- def is_a_material_set(cls, material):
+ def is_a_material_set(cls, material: ifcopenshell.entity_instance) -> bool:
return material.is_a() in [
"IfcMaterialConstituentSet",
"IfcMaterialLayerSet",
@@ -154,7 +158,9 @@ class Material(blenderbim.core.tool.Material):
]
@classmethod
- def add_material_to_set(cls, material_set, material):
+ def add_material_to_set(
+ cls, material_set: ifcopenshell.entity_instance, material: ifcopenshell.entity_instance
+ ) -> None:
if material_set.is_a("IfcMaterialConstituentSet"):
if not material_set.MaterialConstituents:
tool.Ifc.run(
@@ -195,7 +201,7 @@ class Material(blenderbim.core.tool.Material):
)
@classmethod
- def has_material_profile(cls, element):
+ def has_material_profile(cls, element: ifcopenshell.entity_instance) -> bool:
material = cls.get_material(element, should_inherit=False)
inherited_material = cls.get_material(element, should_inherit=True)
if material and "Profile" in material.is_a():
@@ -205,11 +211,13 @@ class Material(blenderbim.core.tool.Material):
return False
@classmethod
- def is_a_flow_segment(cls, element):
+ def is_a_flow_segment(cls, element: ifcopenshell.entity_instance) -> bool:
return element.is_a("IfcFlowSegment")
@classmethod
- def replace_material_with_material_profile(cls, element):
+ def replace_material_with_material_profile(
+ cls, element: ifcopenshell.entity_instance
+ ) -> ifcopenshell.entity_instance:
old_material = cls.get_material(element, should_inherit=False)
old_inherited_material = cls.get_material(element, should_inherit=True)
material = old_material if old_material and old_material.is_a("IfcMaterial") else None
@@ -225,14 +233,14 @@ class Material(blenderbim.core.tool.Material):
return material_profile
@classmethod
- def update_elements_using_material(cls, material):
+ def update_elements_using_material(cls, material: ifcopenshell.entity_instance) -> None:
# update elements that are using this material
elements = ifcopenshell.util.element.get_elements_by_material(tool.Ifc.get(), material)
objects = [tool.Ifc.get_object(e) for e in elements]
tool.Geometry.reload_representation(objects)
@classmethod
- def sync_blender_material_name(cls, material):
+ def sync_blender_material_name(cls, material: ifcopenshell.entity_instance) -> None:
name = material.Name or "Unnamed"
obj = tool.Ifc.get_object(material)
if obj:
@@ -245,7 +253,7 @@ class Material(blenderbim.core.tool.Material):
obj.name = name
@classmethod
- def get_style(cls, material):
+ def get_style(cls, material: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
for material_representation in material.HasRepresentation:
for representation in material_representation.Representations:
for item in representation.Items:
diff --git a/src/blenderbim/blenderbim/tool/profile.py b/src/blenderbim/blenderbim/tool/profile.py
index c0295be0c7..10e8613694 100644
--- a/src/blenderbim/blenderbim/tool/profile.py
+++ b/src/blenderbim/blenderbim/tool/profile.py
@@ -17,18 +17,23 @@
# along with BlenderBIM Add-on. If not, see .
import ifcopenshell
+import ifcopenshell.geom
import ifcopenshell.util.element
import ifcopenshell.util.unit
import ifcopenshell.util.placement
import ifcopenshell.util.representation
import blenderbim.core.tool
import blenderbim.tool as tool
+import PIL.ImageDraw
from blenderbim.bim.module.model.decorator import ProfileDecorator
+from typing import Union
class Profile(blenderbim.core.tool.Profile):
@classmethod
- def draw_image_for_ifc_profile(cls, draw, profile, size):
+ def draw_image_for_ifc_profile(
+ cls, draw: PIL.ImageDraw.ImageDraw, profile: ifcopenshell.entity_instance, size: float
+ ) -> None:
"""generates image based on `profile` using `PIL.ImageDraw`"""
settings = ifcopenshell.geom.settings()
settings.set(settings.INCLUDE_CURVES, True)
@@ -57,11 +62,11 @@ class Profile(blenderbim.core.tool.Profile):
draw.line((tuple(grouped_verts[e[0]]), tuple(grouped_verts[e[1]])), fill="white", width=2)
@classmethod
- def is_editing_profile(cls):
- return ProfileDecorator.installed
+ def is_editing_profile(cls) -> bool:
+ return bool(ProfileDecorator.installed)
@classmethod
- def get_profile(cls, element):
+ def get_profile(cls, element: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
representations = element.Representation
for representation in representations.Representations:
if not representation.is_a("IfcShapeRepresentation"):
@@ -74,7 +79,7 @@ class Profile(blenderbim.core.tool.Profile):
return None
@classmethod
- def get_model_profiles(cls):
+ def get_model_profiles(cls) -> list[ifcopenshell.entity_instance]:
return tool.Ifc.get().by_type("IfcProfileDef")
@classmethod
diff --git a/src/blenderbim/blenderbim/tool/root.py b/src/blenderbim/blenderbim/tool/root.py
index f1f36d6933..057644e9f5 100644
--- a/src/blenderbim/blenderbim/tool/root.py
+++ b/src/blenderbim/blenderbim/tool/root.py
@@ -21,6 +21,7 @@ import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.representation
import ifcopenshell.util.element
+import ifcopenshell.util.placement
import blenderbim.core.tool
import blenderbim.core.aggregate
import blenderbim.core.geometry
@@ -29,17 +30,17 @@ import blenderbim.core.style
import blenderbim.tool as tool
from mathutils import Vector
from blenderbim.bim.module.model.opening import FilledOpeningGenerator
-from typing import Union, Optional
+from typing import Union, Optional, Any
class Root(blenderbim.core.tool.Root):
@classmethod
- def add_tracked_opening(cls, obj):
+ def add_tracked_opening(cls, obj: bpy.types.Object) -> None:
new = bpy.context.scene.BIMModelProperties.openings.add()
new.obj = obj
@classmethod
- def assign_body_styles(cls, element, obj):
+ def assign_body_styles(cls, element: ifcopenshell.entity_instance, obj: bpy.types.Object) -> None:
# Should this even be here? Should it be in the geometry tool?
body = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
if body:
@@ -56,7 +57,7 @@ class Root(blenderbim.core.tool.Root):
)
@classmethod
- def copy_representation(cls, source, dest):
+ def copy_representation(cls, source: ifcopenshell.entity_instance, dest: ifcopenshell.entity_instance) -> None:
def exclude_callback(attribute):
return attribute.is_a("IfcProfileDef") and attribute.ProfileName
@@ -80,11 +81,13 @@ class Root(blenderbim.core.tool.Root):
]
@classmethod
- def does_type_have_representations(cls, element):
+ def does_type_have_representations(cls, element: ifcopenshell.entity_instance) -> bool:
return bool(element.RepresentationMaps)
@classmethod
- def get_decomposition_relationships(cls, objs):
+ def get_decomposition_relationships(
+ cls, objs: list[bpy.types.Object]
+ ) -> dict[ifcopenshell.entity_instance, dict[str, Any]]:
relationships = {}
for obj in objs:
element = tool.Ifc.get_entity(obj)
@@ -96,7 +99,9 @@ class Root(blenderbim.core.tool.Root):
return relationships
@classmethod
- def get_connection_relationships(cls, objs):
+ def get_connection_relationships(
+ cls, objs: list[bpy.types.Object]
+ ) -> dict[ifcopenshell.entity_instance, dict[str, Any]]:
relationships = {}
for obj in objs:
element = tool.Ifc.get_entity(obj)
@@ -119,7 +124,9 @@ class Root(blenderbim.core.tool.Root):
return relationships
@classmethod
- def get_element_representation(cls, element, context):
+ def get_element_representation(
+ cls, element: ifcopenshell.entity_instance, context: ifcopenshell.entity_instance
+ ) -> Union[ifcopenshell.entity_instance, None]:
if context.is_a("IfcGeometricRepresentationSubContext"):
return ifcopenshell.util.representation.get_representation(
element,
@@ -134,13 +141,13 @@ class Root(blenderbim.core.tool.Root):
return ifcopenshell.util.element.get_type(element)
@classmethod
- def get_object_name(cls, obj):
+ def get_object_name(cls, obj: bpy.types.Object) -> None:
if "." in obj.name and obj.name.split(".")[-1].isnumeric():
return ".".join(obj.name.split(".")[:-1])
return obj.name
@classmethod
- def get_object_representation(cls, obj):
+ def get_object_representation(cls, obj: bpy.types.Object) -> Union[ifcopenshell.entity_instance, None]:
if obj.data and obj.data.BIMMeshProperties.ifc_definition_id:
return tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
element = tool.Ifc.get_entity(obj)
@@ -152,19 +159,21 @@ class Root(blenderbim.core.tool.Root):
return element.Representation.Representations[0]
@classmethod
- def get_representation_context(cls, representation):
+ def get_representation_context(cls, representation: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
return representation.ContextOfItems
@classmethod
- def is_element_a(cls, element, ifc_class):
+ def is_element_a(cls, element: ifcopenshell.entity_instance, ifc_class: str) -> bool:
return element.is_a(ifc_class)
@classmethod
- def link_object_data(cls, source_obj, destination_obj):
+ def link_object_data(cls, source_obj: bpy.types.Object, destination_obj: bpy.types.Object) -> None:
destination_obj.data = source_obj.data
@classmethod
- def recreate_decompositions(cls, relationships, old_to_new):
+ def recreate_decompositions(
+ cls, relationships, old_to_new: dict[ifcopenshell.entity_instance, list[ifcopenshell.entity_instance]]
+ ) -> None:
for subelement, data in relationships.items():
new_subelements = old_to_new.get(subelement)
new_elements = old_to_new.get(data["element"])
@@ -227,7 +236,11 @@ class Root(blenderbim.core.tool.Root):
)
@classmethod
- def recreate_connections(cls, relationship, old_to_new):
+ def recreate_connections(
+ cls,
+ relationship: dict[ifcopenshell.entity_instance, dict[str, Any]],
+ old_to_new: dict[ifcopenshell.entity_instance, list[ifcopenshell.entity_instance]],
+ ) -> None:
for element, data in relationship.items():
try:
new_relating_element = old_to_new.get(data["relating_element"])[0]
@@ -244,7 +257,9 @@ class Root(blenderbim.core.tool.Root):
)
@classmethod
- def recreate_aggregate(cls, old_to_new):
+ def recreate_aggregate(
+ cls, old_to_new: dict[ifcopenshell.entity_instance, list[ifcopenshell.entity_instance]]
+ ) -> None:
for old, new in old_to_new.items():
old_aggregate = ifcopenshell.util.element.get_aggregate(old)
if old_aggregate:
@@ -301,7 +316,7 @@ class Root(blenderbim.core.tool.Root):
)
@classmethod
- def set_object_name(cls, obj, element):
+ def set_object_name(cls, obj: bpy.types.Object, element: ifcopenshell.entity_instance) -> None:
# This disables the Blender name event handler
obj.BIMObjectProperties.is_renaming = True
name = getattr(element, "Name", getattr(element, "AxisTag", None))
@@ -309,7 +324,7 @@ class Root(blenderbim.core.tool.Root):
obj.BIMObjectProperties.is_renaming = False
@classmethod
- def unlink_object(cls, obj):
+ def unlink_object(cls, obj: bpy.types.Object) -> None:
tool.Ifc.unlink(obj=obj)
if hasattr(obj.data, "BIMMeshProperties"):
obj.data.BIMMeshProperties.ifc_definition_id = 0
diff --git a/src/blenderbim/blenderbim/tool/style.py b/src/blenderbim/blenderbim/tool/style.py
index 9ff8c9aa4c..ae99214599 100644
--- a/src/blenderbim/blenderbim/tool/style.py
+++ b/src/blenderbim/blenderbim/tool/style.py
@@ -20,11 +20,12 @@ import bpy
import numpy as np
import ifcopenshell
import ifcopenshell.util.element
+import ifcopenshell.util.representation
import blenderbim.core.tool
import blenderbim.tool as tool
import blenderbim.bim.helper
from mathutils import Color
-from typing import Union
+from typing import Union, Any, Optional
# fmt: off
TEXTURE_MAPS_BY_METHODS = {
@@ -45,19 +46,19 @@ STYLE_PROPS_MAP = {
class Style(blenderbim.core.tool.Style):
@classmethod
- def can_support_rendering_style(cls, obj):
+ def can_support_rendering_style(cls, obj: bpy.types.Material) -> bool:
return obj.use_nodes and hasattr(obj.node_tree, "nodes")
@classmethod
- def disable_editing(cls, obj):
+ def disable_editing(cls, obj: bpy.types.Material) -> None:
obj.BIMStyleProperties.is_editing = False
@classmethod
- def disable_editing_external_style(cls, obj):
+ def disable_editing_external_style(cls, obj: bpy.types.Material) -> None:
obj.BIMStyleProperties.is_editing_external_style = False
@classmethod
- def disable_editing_styles(cls):
+ def disable_editing_styles(cls) -> None:
bpy.context.scene.BIMStylesProperties.is_editing = False
@classmethod
@@ -67,39 +68,40 @@ class Style(blenderbim.core.tool.Style):
return new_style
@classmethod
- def enable_editing(cls, obj):
+ def enable_editing(cls, obj: bpy.types.Material) -> None:
obj.BIMStyleProperties.is_editing = True
@classmethod
- def enable_editing_external_style(cls, obj):
+ def enable_editing_external_style(cls, obj: bpy.types.Material) -> None:
obj.BIMStyleProperties.is_editing_external_style = True
@classmethod
- def enable_editing_styles(cls):
+ def enable_editing_styles(cls) -> None:
bpy.context.scene.BIMStylesProperties.is_editing = True
@classmethod
- def export_surface_attributes(cls, obj):
+ def export_surface_attributes(cls, obj: bpy.types.Material) -> dict[str, Any]:
return blenderbim.bim.helper.export_attributes(obj.BIMStyleProperties.attributes)
@classmethod
- def export_external_style_attributes(cls, obj):
+ def export_external_style_attributes(cls, obj: bpy.types.Material) -> dict[str, Any]:
return blenderbim.bim.helper.export_attributes(obj.BIMStyleProperties.external_style_attributes)
@classmethod
- def get_active_style_type(cls):
+ def get_active_style_type(cls) -> str:
return bpy.context.scene.BIMStylesProperties.style_type
+ # TODO: `obj` argument is unused?
@classmethod
- def get_context(cls, obj):
+ def get_context(cls, obj) -> Union[ifcopenshell.entity_instance, None]:
return ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW")
@classmethod
- def get_elements_by_style(cls, style):
+ def get_elements_by_style(cls, style: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
return ifcopenshell.util.element.get_elements_by_style(tool.Ifc.get(), style)
@classmethod
- def get_name(cls, obj):
+ def get_name(cls, obj: bpy.types.Material) -> str:
return obj.name
@classmethod
@@ -126,7 +128,7 @@ class Style(blenderbim.core.tool.Style):
return style_elements
@classmethod
- def get_shading_style_data_from_props(cls) -> dict:
+ def get_shading_style_data_from_props(cls) -> dict[str, Any]:
"""returns style data from blender props in similar way to `Loader.surface_style_to_dict`
to be compatible with `Loader.create_surface_style_rendering`"""
surface_style_data = dict()
@@ -154,7 +156,7 @@ class Style(blenderbim.core.tool.Style):
return surface_style_data
@classmethod
- def get_texture_style_data_from_props(cls) -> list[dict]:
+ def get_texture_style_data_from_props(cls) -> list[dict[str, Any]]:
"""returns style data from blender props in similar way to `Loader.surface_texture_to_dict`
to be compatible with `Loader.create_surface_style_with_textures`"""
props = bpy.context.scene.BIMStylesProperties
@@ -174,7 +176,7 @@ class Style(blenderbim.core.tool.Style):
return textures
@classmethod
- def set_surface_style_props(cls):
+ def set_surface_style_props(cls) -> None:
"""set blender style props based on currently edited IfcSurfaceStyle,
reset unrelated props to default values"""
@@ -241,7 +243,7 @@ class Style(blenderbim.core.tool.Style):
props["update_graph"] = prev_update_graph_value
@classmethod
- def get_surface_rendering_attributes(cls, obj, verbose=False):
+ def get_surface_rendering_attributes(cls, obj: bpy.types.Material, verbose: bool = False) -> dict[str, Any]:
report = (lambda *x: print(*x)) if verbose else (lambda *x: None)
def color_to_ifc_format(color):
@@ -403,22 +405,22 @@ class Style(blenderbim.core.tool.Style):
return attributes
@classmethod
- def get_surface_rendering_style(cls, obj):
+ def get_surface_rendering_style(cls, obj: bpy.types.Material) -> Union[ifcopenshell.entity_instance, None]:
style_elements = cls.get_style_elements(obj)
return style_elements.get("IfcSurfaceStyleRendering", None)
@classmethod
- def get_texture_style(cls, obj):
+ def get_texture_style(cls, obj: bpy.types.Material) -> Union[ifcopenshell.entity_instance, None]:
style_elements = cls.get_style_elements(obj)
return style_elements.get("IfcSurfaceStyleWithTextures", None)
@classmethod
- def get_external_style(cls, obj):
+ def get_external_style(cls, obj: bpy.types.Material) -> Union[ifcopenshell.entity_instance, None]:
style_elements = cls.get_style_elements(obj)
return style_elements.get("IfcExternallyDefinedSurfaceStyle", None)
@classmethod
- def get_surface_shading_attributes(cls, obj):
+ def get_surface_shading_attributes(cls, obj: bpy.types.Material) -> dict[str, Any]:
data = {
"SurfaceColour": {
"Name": None,
@@ -433,7 +435,7 @@ class Style(blenderbim.core.tool.Style):
return data
@classmethod
- def get_surface_shading_style(cls, obj):
+ def get_surface_shading_style(cls, obj: bpy.types.Material) -> Union[ifcopenshell.entity_instance, None]:
if obj.BIMMaterialProperties.ifc_style_id:
style = tool.Ifc.get().by_id(obj.BIMMaterialProperties.ifc_style_id)
items = [s for s in style.Styles if s.is_a() == "IfcSurfaceStyleShading"]
@@ -441,7 +443,7 @@ class Style(blenderbim.core.tool.Style):
return items[0]
@classmethod
- def get_surface_texture_style(cls, obj):
+ def get_surface_texture_style(cls, obj: bpy.types.Material) -> Union[ifcopenshell.entity_instance, None]:
if obj.BIMMaterialProperties.ifc_style_id:
style = tool.Ifc.get().by_id(obj.BIMMaterialProperties.ifc_style_id)
items = [s for s in style.Styles if s.is_a("IfcSurfaceStyleWithTextures")]
@@ -449,7 +451,7 @@ class Style(blenderbim.core.tool.Style):
return items[0]
@classmethod
- def get_uv_maps(cls, representation):
+ def get_uv_maps(cls, representation: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
items = []
for item in representation.Items:
if item.is_a("IfcMappedItem"):
@@ -464,7 +466,7 @@ class Style(blenderbim.core.tool.Style):
return results
@classmethod
- def get_style_ui_props_attributes(cls, style_type):
+ def get_style_ui_props_attributes(cls, style_type: str) -> Union[bpy.types.PropertyGroup, None]:
props = bpy.context.scene.BIMStylesProperties
if style_type == "IfcExternallyDefinedSurfaceStyle":
return props.external_style_attributes
@@ -474,7 +476,7 @@ class Style(blenderbim.core.tool.Style):
return props.lighting_style_colours
@classmethod
- def import_presentation_styles(cls, style_type):
+ def import_presentation_styles(cls, style_type: str) -> None:
color_to_tuple = lambda x: (x.Red, x.Green, x.Blue)
props = bpy.context.scene.BIMStylesProperties
props.styles.clear()
@@ -497,13 +499,13 @@ class Style(blenderbim.core.tool.Style):
new.total_elements = len(ifcopenshell.util.element.get_elements_by_style(tool.Ifc.get(), style))
@classmethod
- def import_surface_attributes(cls, style, obj):
+ def import_surface_attributes(cls, style: ifcopenshell.entity_instance, obj: bpy.types.Material) -> None:
attributes = obj.BIMStyleProperties.attributes
attributes.clear()
blenderbim.bim.helper.import_attributes2(style, attributes)
@classmethod
- def import_external_style_attributes(cls, style, obj):
+ def import_external_style_attributes(cls, style: ifcopenshell.entity_instance, obj: bpy.types.Material) -> None:
attributes = obj.BIMStyleProperties.external_style_attributes
attributes.clear()
blenderbim.bim.helper.import_attributes2(style, attributes)
@@ -514,26 +516,26 @@ class Style(blenderbim.core.tool.Style):
return bool(external_style and external_style.Location and external_style.Location.endswith(".blend"))
@classmethod
- def is_editing_styles(cls):
+ def is_editing_styles(cls) -> bool:
return bpy.context.scene.BIMStylesProperties.is_editing
@classmethod
- def record_shading(cls, obj):
+ def record_shading(cls, obj: bpy.types.Material) -> None:
obj.BIMMaterialProperties.shading_checksum = repr(np.array(obj.diffuse_color).tobytes())
@classmethod
- def select_elements(cls, elements):
+ def select_elements(cls, elements: list[ifcopenshell.entity_instance]) -> None:
for element in elements:
obj = tool.Ifc.get_object(element)
if obj:
obj.select_set(True)
@classmethod
- def change_current_style_type(cls, blender_material, style_type):
+ def change_current_style_type(cls, blender_material: bpy.types.Material, style_type: str) -> None:
blender_material.BIMStyleProperties.active_style_type = style_type
@classmethod
- def get_styled_items(cls, style):
+ def get_styled_items(cls, style: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
ifc_file = tool.Ifc.get()
inverses = list(ifc_file.get_inverse(style))
@@ -554,13 +556,15 @@ class Style(blenderbim.core.tool.Style):
return items
@classmethod
- def assign_style_to_object(cls, style, obj):
+ def assign_style_to_object(cls, style: ifcopenshell.entity_instance, obj: bpy.types.Object) -> None:
"""assigns `style` to `object` current representation"""
representation = tool.Geometry.get_active_representation(obj)
tool.Ifc.run("style.assign_representation_styles", shape_representation=representation, styles=[style])
@classmethod
- def assign_style_to_representation_item(cls, representation_item, style=None):
+ def assign_style_to_representation_item(
+ cls, representation_item: ifcopenshell.entity_instance, style: Optional[ifcopenshell.entity_instance] = None
+ ) -> None:
ifc_file = tool.Ifc.get()
if not representation_item.StyledByItem:
if style is None:
@@ -574,12 +578,14 @@ class Style(blenderbim.core.tool.Style):
styled_item.Styles = (style,)
@classmethod
- def get_representation_item_style(cls, representation_item):
+ def get_representation_item_style(
+ cls, representation_item: ifcopenshell.entity_instance
+ ) -> Union[ifcopenshell.entity_instance, None]:
for inverse in tool.Ifc.get().get_inverse(representation_item):
if inverse.is_a("IfcStyledItem"):
for style in inverse.Styles:
return style
@classmethod
- def reload_material_from_ifc(cls, blender_material):
+ def reload_material_from_ifc(cls, blender_material: bpy.types.Material) -> None:
blender_material.BIMStyleProperties.active_style_type = blender_material.BIMStyleProperties.active_style_type
diff --git a/src/ifc5d/ifc5d/ifc5Dspreadsheet.py b/src/ifc5d/ifc5d/ifc5Dspreadsheet.py
index b870329d20..31dd3e2d7a 100644
--- a/src/ifc5d/ifc5d/ifc5Dspreadsheet.py
+++ b/src/ifc5d/ifc5d/ifc5Dspreadsheet.py
@@ -26,7 +26,7 @@ import ifcopenshell
import ifcopenshell.util.element
import ifcopenshell.util.cost
import ifcopenshell.util.date
-from typing import Union, Optional
+from typing import Union, Optional, Any
class IfcDataGetter:
@@ -41,17 +41,17 @@ class IfcDataGetter:
]
@staticmethod
- def canonicalise_time(time):
+ def canonicalise_time(time: Union[datetime.datetime, None]) -> str:
if not time:
return "-"
return time.strftime("%d/%m/%y")
@staticmethod
- def get_root_costs(cost_schedule):
+ def get_root_costs(cost_schedule: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
return [obj for rel in cost_schedule.Controls or [] for obj in rel.RelatedObjects or []]
@staticmethod
- def get_cost_item_values(cost_item=None):
+ def get_cost_item_values(cost_item: Union[ifcopenshell.entity_instance, None]) -> Union[list[dict[str, Any]], None]:
if not cost_item:
return None
values = []
@@ -71,14 +71,14 @@ class IfcDataGetter:
return values
@staticmethod
- def process_categories(cost_item, categories):
+ def process_categories(cost_item: ifcopenshell.entity_instance, categories: set[str]) -> set[str]:
for cost_value in cost_item.CostValues or []:
if cost_value.Category:
categories.add("{}{}".format(cost_value.Category, " Cost"))
return categories
@staticmethod
- def process_cost_item_categories(cost_item, categories):
+ def process_cost_item_categories(cost_item: ifcopenshell.entity_instance, categories: set[str]) -> set[str]:
IfcDataGetter.process_categories(cost_item, categories)
for rel in cost_item.IsNestedBy or []:
for child in rel.RelatedObjects or []:
@@ -86,14 +86,20 @@ class IfcDataGetter:
return categories
@staticmethod
- def get_cost_rates_categories(schedule):
+ def get_cost_rates_categories(schedule: ifcopenshell.entity_instance) -> set[str]:
categories = set()
for cost_item in IfcDataGetter.get_root_costs(schedule):
IfcDataGetter.process_cost_item_categories(cost_item, categories)
return categories
@staticmethod
- def process_cost_data(file, cost_item, cost_items_data, index, hierarchy="1"):
+ def process_cost_data(
+ file: ifcopenshell.file,
+ cost_item: ifcopenshell.entity_instance,
+ cost_items_data: list[dict[str, Any]],
+ index: int,
+ hierarchy: str = "1",
+ ) -> None:
def listToString(s):
return ", ".join([str(i) for i in s])
@@ -134,7 +140,7 @@ class IfcDataGetter:
)
@staticmethod
- def get_cost_items_data(file, schedule):
+ def get_cost_items_data(file: ifcopenshell.file, schedule: ifcopenshell.entity_instance) -> list[dict[str, Any]]:
cost_items_data = []
index = 0
for cost_item in IfcDataGetter.get_root_costs(schedule):
@@ -142,7 +148,7 @@ class IfcDataGetter:
return cost_items_data
@staticmethod
- def format_unit(unit):
+ def format_unit(unit: ifcopenshell.entity_instance) -> str:
if unit.is_a("IfcContextDependentUnit"):
return f"{unit.UnitType} / {unit.Name}"
else:
@@ -152,7 +158,7 @@ class IfcDataGetter:
return f"{unit.UnitType} / {name}"
@staticmethod
- def get_cost_value_unit(cost_value=None):
+ def get_cost_value_unit(cost_value: Optional[ifcopenshell.entity_instance] = None) -> Union[str, None]:
if not cost_value:
return None
unit = cost_value.UnitBasis
@@ -161,9 +167,9 @@ class IfcDataGetter:
return IfcDataGetter.format_unit(unit.UnitComponent)
@staticmethod
- def get_cost_item_quantity(file, cost_item=None):
+ def get_cost_item_quantity(file: ifcopenshell.file, cost_item: ifcopenshell.entity_instance) -> dict[str, Any]:
# TODO: handle multiple quantities, THOSE WHHICH ARE JUYST ASSIGNED TO THE COST ITEM DIRECTLY, NOT THROUGH OBJECTS.
- def add_quantity(quantity, take_off_name):
+ def add_quantity(quantity: ifcopenshell.entity_instance, take_off_name: str) -> float:
accounted_for.append(quantity)
if take_off_name == "":
take_off_name = quantity[0]
diff --git a/src/ifcopenshell-python/ifcopenshell/util/element.py b/src/ifcopenshell-python/ifcopenshell/util/element.py
index 76366c2f0e..89999deb5b 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/element.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/element.py
@@ -833,7 +833,7 @@ def get_layers(
def get_container(
element: ifcopenshell.entity_instance, should_get_direct: bool = False, ifc_class: Optional[str] = None
-) -> ifcopenshell.entity_instance:
+) -> Union[ifcopenshell.entity_instance, None]:
"""
Retrieves the spatial structure container of an element.
@@ -849,7 +849,7 @@ def get_container(
example, you may be after the storey, not a space.
:type ifc_class: str, optional
:return: The direct or indirect container of the element or None.
- :rtype: ifcopenshell.entity_instance
+ :rtype: Union[ifcopenshell.entity_instance, None]
Example: