diff --git a/src/blenderbim/blenderbim/bim/handler.py b/src/blenderbim/blenderbim/bim/handler.py
index 28306671de..9ebe90c5e7 100644
--- a/src/blenderbim/blenderbim/bim/handler.py
+++ b/src/blenderbim/blenderbim/bim/handler.py
@@ -223,7 +223,7 @@ def redo_post(scene):
tool.Ifc.rebuild_element_maps()
-def get_application(ifc):
+def get_application(ifc: ifcopenshell.file) -> ifcopenshell.entity_instance:
# TODO: cache this for even faster application retrieval. It honestly makes a difference on long scripts.
version = get_application_version()
for element in ifc.by_type("IfcApplication"):
@@ -238,7 +238,7 @@ def get_application(ifc):
)
-def get_application_version():
+def get_application_version() -> str:
return ".".join(
[
str(x)
diff --git a/src/blenderbim/blenderbim/tool/owner.py b/src/blenderbim/blenderbim/tool/owner.py
index bd5f068adc..b805112689 100644
--- a/src/blenderbim/blenderbim/tool/owner.py
+++ b/src/blenderbim/blenderbim/tool/owner.py
@@ -19,6 +19,8 @@
import bpy
import blenderbim.core.tool
import blenderbim.tool as tool
+import ifcopenshell
+from typing import Union
class Owner(blenderbim.core.tool.Owner):
@@ -27,7 +29,7 @@ class Owner(blenderbim.core.tool.Owner):
bpy.context.scene.BIMOwnerProperties.active_user_id = user.id()
@classmethod
- def get_user(cls):
+ def get_user(cls) -> Union[ifcopenshell.entity_instance, None]:
if bpy.context.scene.BIMOwnerProperties.active_user_id:
return tool.Ifc.get().by_id(bpy.context.scene.BIMOwnerProperties.active_user_id)
elif tool.Ifc.get_schema() == "IFC2X3":
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py
index 0e71411464..23b07f0c03 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py
@@ -17,20 +17,34 @@
# along with IfcOpenShell. If not, see .
import numpy as np
+import numpy.typing as npt
import ifcopenshell.api
import ifcopenshell.util.unit
import ifcopenshell.util.element
import ifcopenshell.util.placement
+from typing import Optional, Union
+
+NPArrayOfFloats = npt.NDArray[np.float64]
class Usecase:
- def __init__(self, file, **settings):
+ def __init__(
+ self,
+ file: ifcopenshell.file,
+ product: ifcopenshell.entity_instance,
+ matrix: Optional[NPArrayOfFloats] = None,
+ is_si=True,
+ should_transform_children=False,
+ ):
self.file = file
- self.settings = {"product": None, "matrix": np.eye(4), "is_si": True, "should_transform_children": False}
- for key, value in settings.items():
- self.settings[key] = value
+ self.settings = {
+ "product": product,
+ "matrix": matrix if matrix is not None else np.eye(4),
+ "is_si": is_si,
+ "should_transform_children": should_transform_children,
+ }
- def execute(self):
+ def execute(self) -> ifcopenshell.entity_instance:
if not hasattr(self.settings["product"], "ObjectPlacement"):
return
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(self.file)
@@ -69,12 +83,12 @@ class Usecase:
return new_placement
- def convert_matrix_to_si(self, matrix):
+ def convert_matrix_to_si(self, matrix: NPArrayOfFloats):
matrix[0][3] *= self.unit_scale
matrix[1][3] *= self.unit_scale
matrix[2][3] *= self.unit_scale
- def get_placement_rel_to(self):
+ def get_placement_rel_to(self) -> Union[ifcopenshell.entity_instance, None]:
if getattr(self.settings["product"], "Decomposes", None):
relating_object = self.settings["product"].Decomposes[0].RelatingObject
return relating_object.ObjectPlacement if hasattr(relating_object, "ObjectPlacement") else None
@@ -96,7 +110,7 @@ class Usecase:
elif getattr(self.settings["product"], "ContainedInStructure", None):
return self.settings["product"].ContainedInStructure[0].RelatingStructure.ObjectPlacement
- def get_children_settings(self, placement):
+ def get_children_settings(self, placement: Union[ifcopenshell.entity_instance, None]) -> list[dict]:
if not placement:
return []
results = []
@@ -116,7 +130,9 @@ class Usecase:
results.append({"product": obj, "matrix": matrix, "is_si": False, "should_transform_children": True})
return results
- def get_relative_placement(self, placement_rel_to):
+ def get_relative_placement(
+ self, placement_rel_to: Union[ifcopenshell.entity_instance, None]
+ ) -> ifcopenshell.entity_instance:
if placement_rel_to:
relating_object_matrix = ifcopenshell.util.placement.get_local_placement(placement_rel_to)
relating_object_matrix[0][3] = self.convert_unit_to_si(relating_object_matrix[0][3])
@@ -136,19 +152,21 @@ class Usecase:
relative_placement_matrix[:, 0][0:3],
)
- def create_ifc_axis_2_placement_3d(self, point, up, forward):
+ def create_ifc_axis_2_placement_3d(
+ self, point: NPArrayOfFloats, up: NPArrayOfFloats, forward: NPArrayOfFloats
+ ) -> ifcopenshell.entity_instance:
return self.file.createIfcAxis2Placement3D(
self.create_cartesian_point(point),
self.file.createIfcDirection(up.tolist()),
self.file.createIfcDirection(forward.tolist()),
)
- def create_cartesian_point(self, co):
+ def create_cartesian_point(self, co: NPArrayOfFloats) -> ifcopenshell.entity_instance:
co = self.convert_si_to_unit(co)
return self.file.createIfcCartesianPoint(co.tolist())
- def convert_si_to_unit(self, co):
+ def convert_si_to_unit(self, co: NPArrayOfFloats) -> NPArrayOfFloats:
return co / self.unit_scale
- def convert_unit_to_si(self, co):
+ def convert_unit_to_si(self, co: NPArrayOfFloats) -> NPArrayOfFloats:
return co * self.unit_scale
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/add_organisation.py b/src/ifcopenshell-python/ifcopenshell/api/owner/add_organisation.py
index db4121d9cb..0e6f676fbc 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/add_organisation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/add_organisation.py
@@ -15,10 +15,11 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import ifcopenshell
class Usecase:
- def __init__(self, file, identification="APTR", name="Aperture Science"):
+ def __init__(self, file: ifcopenshell.file, identification: str = "APTR", name: str = "Aperture Science"):
"""Adds a new organisation
Organisations are the main way to identify manufacturers, suppliers, and
@@ -45,7 +46,7 @@ class Usecase:
self.file = file
self.settings = {"identification": identification, "name": name}
- def execute(self):
+ def execute(self) -> ifcopenshell.entity_instance:
data = {"Name": self.settings["name"]}
if self.file.schema == "IFC2X3":
data["Id"] = self.settings["identification"]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/add_person.py b/src/ifcopenshell-python/ifcopenshell/api/owner/add_person.py
index 308d771e21..268568c80d 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/add_person.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/add_person.py
@@ -15,10 +15,17 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import ifcopenshell
class Usecase:
- def __init__(self, file, identification="HSeldon", family_name="Seldon", given_name="Hari"):
+ def __init__(
+ self,
+ file: ifcopenshell.entity_instance,
+ identification: str = "HSeldon",
+ family_name: str = "Seldon",
+ given_name: str = "Hari",
+ ):
"""Adds a new person
Persons are used to identify a legal or liable representative of an
@@ -48,7 +55,7 @@ class Usecase:
"given_name": given_name,
}
- def execute(self):
+ def execute(self) ->ifcopenshell.entity_instance:
data = {"FamilyName": self.settings["family_name"], "GivenName": self.settings["given_name"]}
if self.file.schema == "IFC2X3":
data["Id"] = self.settings["identification"]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/add_person_and_organisation.py b/src/ifcopenshell-python/ifcopenshell/api/owner/add_person_and_organisation.py
index 05c137b516..3e0b372690 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/add_person_and_organisation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/add_person_and_organisation.py
@@ -15,10 +15,16 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import ifcopenshell
class Usecase:
- def __init__(self, file, person=None, organisation=None):
+ def __init__(
+ self,
+ file: ifcopenshell.entity_instance,
+ person: ifcopenshell.entity_instance,
+ organisation: ifcopenshell.entity_instance,
+ ):
"""Adds a paired person and organisation
A person and an organisation may be paired to create a representative
@@ -47,5 +53,5 @@ class Usecase:
self.file = file
self.settings = {"person": person, "organisation": organisation}
- def execute(self):
+ def execute(self) -> ifcopenshell.entity_instance:
return self.file.createIfcPersonAndOrganization(self.settings["person"], self.settings["organisation"])
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/create_owner_history.py b/src/ifcopenshell-python/ifcopenshell/api/owner/create_owner_history.py
index 4ae66cb45e..31491feeaa 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/create_owner_history.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/create_owner_history.py
@@ -19,10 +19,11 @@
import time
import ifcopenshell
import ifcopenshell.api.owner.settings
+from typing import Union
class Usecase:
- def __init__(self, file):
+ def __init__(self, file: ifcopenshell.entity_instance):
"""Creates a new owner history indicating an element was added
Any object in IFC with a unique ID and name (such as physical products,
@@ -59,8 +60,9 @@ class Usecase:
are writing your own advanced scripts and want to take advantage of the
easier ownership tracking.
- :return: The newly created IfcOwnerHistory element.
- :rtype: ifcopenshell.entity_instance.entity_instance
+ :return: The newly created IfcOwnerHistory element or `None` if it's
+ not IFC2X3 and user or application is not found in the current project.
+ :rtype: Union[ifcopenshell.entity_instance.entity_instance, None]
Example:
@@ -99,7 +101,7 @@ class Usecase:
self.file = file
self.settings = {}
- def execute(self):
+ def execute(self) -> Union[ifcopenshell.entity_instance, None]:
user = ifcopenshell.api.owner.settings.get_user(self.file)
if self.file.schema != "IFC2X3" and not user:
return
diff --git a/src/ifcopenshell-python/ifcopenshell/api/void/add_opening.py b/src/ifcopenshell-python/ifcopenshell/api/void/add_opening.py
index de479a1d39..3a260a08f7 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/void/add_opening.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/void/add_opening.py
@@ -23,7 +23,9 @@ import ifcopenshell.util.placement
class Usecase:
- def __init__(self, file, opening=None, element=None):
+ def __init__(
+ self, file: ifcopenshell.file, opening: ifcopenshell.entity_instance, element: ifcopenshell.entity_instance
+ ):
"""Create an opening in an element
It is often necessary to cut out openings in elements like walls and
@@ -103,18 +105,18 @@ class Usecase:
self.file = file
self.settings = {"opening": opening, "element": element}
- def execute(self):
+ def execute(self) -> ifcopenshell.entity_instance:
voids_elements = self.settings["opening"].VoidsElements
if voids_elements:
if voids_elements[0].RelatingBuildingElement == self.settings["element"]:
- return
+ return voids_elements[0]
history = voids_elements[0].OwnerHistory
self.file.remove(voids_elements[0])
if history:
ifcopenshell.util.element.remove_deep2(self.file, history)
- self.file.create_entity(
+ rel = self.file.create_entity(
"IfcRelVoidsElement",
**{
"GlobalId": ifcopenshell.guid.new(),
@@ -133,3 +135,5 @@ class Usecase:
matrix=ifcopenshell.util.placement.get_local_placement(self.settings["opening"].ObjectPlacement),
is_si=False,
)
+
+ return rel
diff --git a/src/ifcopenshell-python/ifcopenshell/api/void/remove_opening.py b/src/ifcopenshell-python/ifcopenshell/api/void/remove_opening.py
index 6ed1079b41..3735d2e735 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/void/remove_opening.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/void/remove_opening.py
@@ -17,10 +17,11 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell.api
+import ifcopenshell.util.element
class Usecase:
- def __init__(self, file, opening=None):
+ def __init__(self, file: ifcopenshell.entity_instance, opening: ifcopenshell.entity_instance):
"""Remove an opening
Fillings are retained as orphans. Voided elements remain. Openings
@@ -47,7 +48,7 @@ class Usecase:
self.file = file
self.settings = {"opening": opening}
- def execute(self):
+ def execute(self) -> None:
for rel in self.settings["opening"].VoidsElements:
history = rel.OwnerHistory
self.file.remove(rel)
diff --git a/src/ifcopenshell-python/ifcopenshell/entity_instance.py b/src/ifcopenshell-python/ifcopenshell/entity_instance.py
index c6802aa4a3..6fba487e6c 100644
--- a/src/ifcopenshell-python/ifcopenshell/entity_instance.py
+++ b/src/ifcopenshell-python/ifcopenshell/entity_instance.py
@@ -67,8 +67,9 @@ def set_unsupported_attribute(*args):
_method_dict = {}
-def register_schema_attributes(schema):
+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()))