diff --git a/pyproject.toml b/pyproject.toml
index 8df2bb8091..b3f08435e5 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -3,7 +3,7 @@ name = "IfcOpenShell"
version = "0.0.0"
dependencies = [
"black==25.12",
- "ruff==0.14.10",
+ "ruff==0.14.13",
"poethepoet",
"gersemi==0.24",
]
diff --git a/src/bonsai/bonsai/bim/module/document/__init__.py b/src/bonsai/bonsai/bim/module/document/__init__.py
index cc71d16306..3881148a18 100644
--- a/src/bonsai/bonsai/bim/module/document/__init__.py
+++ b/src/bonsai/bonsai/bim/module/document/__init__.py
@@ -42,15 +42,12 @@ classes = (
ui.BIM_PT_object_documents,
ui.BIM_UL_documents,
ui.BIM_UL_document_objects,
- ui.BIM_MT_object_documents_context_menu,
)
def register():
bpy.types.Scene.BIMDocumentProperties = bpy.props.PointerProperty(type=prop.BIMDocumentProperties)
- bpy.types.VIEW3D_MT_object_context_menu.append(ui.add_object_documents_context_menu)
def unregister():
del bpy.types.Scene.BIMDocumentProperties
- bpy.types.VIEW3D_MT_object_context_menu.remove(ui.add_object_documents_context_menu)
diff --git a/src/bonsai/bonsai/bim/module/document/ui.py b/src/bonsai/bonsai/bim/module/document/ui.py
index c382f1c721..7688399732 100644
--- a/src/bonsai/bonsai/bim/module/document/ui.py
+++ b/src/bonsai/bonsai/bim/module/document/ui.py
@@ -265,68 +265,3 @@ class BIM_UL_document_objects(UIList):
op = row.operator("bim.unassign_document", text="", icon="X")
op.document = document.ifc_definition_id
op.obj = item.name
-
-
-def add_object_documents_context_menu(self, context):
- if not context.active_object:
- return
-
- if not tool.Blender.get_ifc_definition_id(context.active_object):
- return
-
- self.layout.separator()
- self.layout.menu("BIM_MT_object_documents_context_menu", icon="FILE")
-
-
-class BIM_MT_object_documents_context_menu(bpy.types.Menu):
- bl_idname = "BIM_MT_object_documents_context_menu"
- bl_label = "Documents"
-
- def draw(self, context):
- layout = self.layout
-
- if not context.selected_objects:
- layout.label(text="No documents", icon="INFO")
- return
-
- if len(context.selected_objects) > 1:
- layout.label(text="Select a single object to see its referenced documents", icon="INFO")
- return
-
- obj = context.active_object
- if not obj or not tool.Blender.get_ifc_definition_id(obj):
- layout.label(text="No documents", icon="INFO")
- return
-
- if not ObjectDocumentData.is_loaded:
- ObjectDocumentData.load()
-
- if not ObjectDocumentData.data["documents"]:
- layout.label(text="No Documents", icon="FILE")
- else:
- for document in ObjectDocumentData.data["documents"]:
- row = layout.row(align=True)
-
- with_ifc_icon = document["location"] and document["location"].lower().endswith(".ifc")
- with_url_icon = bool(document["location"])
-
- if with_ifc_icon:
- row.operator("bim.open_ifc_document", icon="HIDE_OFF", text="").uri = document["location"]
- else:
- row.label(text="", icon="BLANK1")
-
- if with_url_icon:
- row.operator("bim.open_uri", icon="URL", text="").uri = document["location"]
- else:
- row.label(text="", icon="BLANK1")
-
- doc_entity = None
- if "id" in document:
- doc_entity = tool.Ifc.get().by_id(document["id"])
-
- if doc_entity and doc_entity.is_a("IfcDocumentReference"):
- display_text = document.get("description") or ""
- else:
- display_text = document.get("name") or ""
-
- row.label(text=f"{document['identification'] or ''}: {display_text}")
diff --git a/src/bonsai/bonsai/bim/module/misc/__init__.py b/src/bonsai/bonsai/bim/module/misc/__init__.py
index 27ab626183..31926217fc 100644
--- a/src/bonsai/bonsai/bim/module/misc/__init__.py
+++ b/src/bonsai/bonsai/bim/module/misc/__init__.py
@@ -22,6 +22,7 @@ from . import ui, prop, operator
classes = (
operator.DrawSystemArrows,
operator.GetConnectedSystemElements,
+ operator.IfcSverchokUseBonsaiFile,
operator.ResizeToStorey,
operator.SetOverrideColour,
operator.SnapSpacesTogether,
diff --git a/src/bonsai/bonsai/bim/module/misc/operator.py b/src/bonsai/bonsai/bim/module/misc/operator.py
index 15fca6b547..ee3c592f3e 100644
--- a/src/bonsai/bonsai/bim/module/misc/operator.py
+++ b/src/bonsai/bonsai/bim/module/misc/operator.py
@@ -348,3 +348,24 @@ class DrawSystemArrows(bpy.types.Operator, tool.Ifc.Operator):
)
)
return matrix
+
+
+class IfcSverchokUseBonsaiFile(bpy.types.Operator, tool.Ifc.Operator):
+ bl_idname = "bim.ifcsverchok_use_bonsai_file"
+ bl_label = "Use Bonsai IFC File"
+ bl_description = "Apply current IfcSverchok tree to the active Bonsai file."
+ bl_options = {"REGISTER", "UNDO"}
+
+ def _execute(self, context):
+ import sverchok.node_tree
+
+ ifc_file = tool.Ifc.get()
+ if ifc_file is None:
+ self.report({"ERROR"}, "No active IFC file.")
+ return {"CANCELLED"}
+
+ space_data = context.space_data
+ assert isinstance(space_data, bpy.types.SpaceNodeEditor)
+ node_tree = space_data.node_tree
+ assert isinstance(node_tree, sverchok.node_tree.SverchCustomTree)
+ tool.Model.run_ifcsverchok_graph_on_bonsai_file(node_tree)
diff --git a/src/bonsai/bonsai/bim/module/model/external.py b/src/bonsai/bonsai/bim/module/model/external.py
index cde84cd536..5ed99f29e8 100644
--- a/src/bonsai/bonsai/bim/module/model/external.py
+++ b/src/bonsai/bonsai/bim/module/model/external.py
@@ -17,9 +17,7 @@
# along with Bonsai. If not, see .
import bpy
-import bmesh
-import ifcopenshell
import bonsai.tool as tool
@@ -32,9 +30,23 @@ class ApplyExternalParametricGeometry(bpy.types.Operator, tool.Ifc.Operator):
def _execute(self, context):
obj = context.active_object
assert obj
- assert (active_representation := tool.Geometry.get_active_representation(obj))
- ifc_context = active_representation.ContextOfItems
- tool.Model.add_representation(obj, ifc_context)
props = tool.Model.get_epg_props(obj)
+
+ # TODO: consider nodes being empty.
+ if props.geometry_source == "GEONODES":
+ assert (active_representation := tool.Geometry.get_active_representation(obj))
+ ifc_context = active_representation.ContextOfItems
+
+ tool.Model.add_representation(obj, ifc_context)
+ elif props.geometry_source == "IFCSVERCHOK":
+ import ifcsverchok.helper as helper
+
+ nodes = props.sverchok_nodes
+ assert nodes is not None
+ tool.Model.run_ifcsverchok_graph_on_bonsai_file(nodes)
+ output_node = tool.Model.get_ifcsverchok_shape_output(nodes)
+ representation = helper.get_socket_value(output_node.inputs, "Representation")
+ tool.Model.replace_object_ifc_representation(representation.ContextOfItems, obj, representation)
+
props.is_editing = False
return {"FINISHED"}
diff --git a/src/bonsai/bonsai/bim/module/model/prop.py b/src/bonsai/bonsai/bim/module/model/prop.py
index 5066ceb9b2..b26466aa15 100644
--- a/src/bonsai/bonsai/bim/module/model/prop.py
+++ b/src/bonsai/bonsai/bim/module/model/prop.py
@@ -33,6 +33,9 @@ from typing import TYPE_CHECKING, Literal, get_args, Union, Any, Optional
from collections.abc import Callable
from mathutils import Vector
+if TYPE_CHECKING:
+ import sverchok.node_tree
+
def get_ifc_class(self: "BIMModelProperties", context: bpy.types.Context) -> list[tuple[str, str, str]]:
if not AuthoringData.is_loaded:
@@ -1709,12 +1712,16 @@ def update_is_editing(self: "BIMExternalParametricGeometryProperties", context:
if self.is_editing:
return
+ assert isinstance(self.id_data, bpy.types.Object)
tool.Model.clean_up_parametric_geometry(self.id_data)
- del self["is_editing"]
- del self["geo_nodes"]
+ self.property_unset("is_editing")
+ self.property_unset("geo_nodes")
+ self.property_unset("sverchok_nodes")
def update_geo_nodes(self: "BIMExternalParametricGeometryProperties", context: bpy.types.Context) -> None:
+ assert isinstance(self.id_data, bpy.types.Object)
+
if self.geo_nodes:
tool.Model.setup_parametric_geometry(self.id_data)
return
@@ -1725,14 +1732,25 @@ def update_geo_nodes(self: "BIMExternalParametricGeometryProperties", context: b
del self["geo_nodes"]
+def poll_sverchok_nodes(self: "BIMExternalParametricGeometryProperties", node_tree: bpy.types.NodeTree) -> bool:
+ return node_tree.bl_idname == "SverchCustomTreeType"
+
+
class BIMExternalParametricGeometryProperties(bpy.types.PropertyGroup):
- is_editing: bpy.props.BoolProperty(
+ is_editing: bpy.props.BoolProperty( # pyright: ignore[reportRedeclaration]
name="Is Editing Paramteric Geometry",
description="Toggle editing parametric geometry.",
default=False,
update=update_is_editing,
)
- geo_nodes: bpy.props.PointerProperty(
+ geometry_source: bpy.props.EnumProperty( # pyright: ignore[reportRedeclaration]
+ name="Geometry Source",
+ items=[
+ ("GEONODES", "Geometry Nodes", ""),
+ ("IFCSVERCHOK", "IFC Sverchok", ""),
+ ],
+ )
+ geo_nodes: bpy.props.PointerProperty( # pyright: ignore[reportRedeclaration]
name="Geometry Nodes",
description="Geometry nodes tree to use as a source for representation.",
type=bpy.types.GeometryNodeTree,
@@ -1740,6 +1758,15 @@ class BIMExternalParametricGeometryProperties(bpy.types.PropertyGroup):
poll=lambda self, node_tree: not node_tree.name.startswith("BBIM_EPG"),
)
+ sverchok_nodes: bpy.props.PointerProperty( # pyright: ignore[reportRedeclaration]
+ name="Sverchok Nodes",
+ description="Sverchok node tree to use as a source for representation.",
+ type=bpy.types.NodeTree,
+ poll=poll_sverchok_nodes,
+ )
+
if TYPE_CHECKING:
is_editing: bool
+ geometry_source: Literal["GEONODES", "IFCSVERCHOK"]
geo_nodes: Union[bpy.types.GeometryNodeTree, None]
+ sverchok_nodes: Union[sverchok.node_tree.SverchCustomTree, None]
diff --git a/src/bonsai/bonsai/bim/module/model/slab.py b/src/bonsai/bonsai/bim/module/model/slab.py
index f5765331b6..4c9e89bf41 100644
--- a/src/bonsai/bonsai/bim/module/model/slab.py
+++ b/src/bonsai/bonsai/bim/module/model/slab.py
@@ -225,7 +225,7 @@ class DumbSlabPlaner:
for inverse in tool.Ifc.get().get_inverse(layer_set):
if not inverse.is_a("IfcMaterialLayerSetUsage") or inverse.LayerSetDirection != "AXIS3":
continue
-
+
if tool.Ifc.get().schema == "IFC2X3":
for rel in tool.Ifc.get().get_inverse(inverse):
if not rel.is_a("IfcRelAssociatesMaterial"):
@@ -277,10 +277,12 @@ class DumbSlabPlaner:
return
self.change_thickness(element, total_thickness)
- def change_thickness(self, element: ifcopenshell.entity_instance, thickness: float, preserve_offset: bool = False) -> None:
+ def change_thickness(
+ self, element: ifcopenshell.entity_instance, thickness: float, preserve_offset: bool = False
+ ) -> None:
if tool.Model.get_usage_type(element) != "LAYER3":
return
-
+
layer_params = tool.Model.get_material_layer_parameters(element)
ifc_file = tool.Ifc.get()
body_context = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW")
@@ -299,7 +301,7 @@ class DumbSlabPlaner:
extrusion = tool.Model.get_extrusion(representation)
if extrusion:
direction_ratios = Vector(extrusion.ExtrudedDirection.DirectionRatios)
-
+
# Calculate the actual extrusion angle from vertical
extrusion_angle = 0
if direction_ratios.length > 0:
diff --git a/src/bonsai/bonsai/bim/module/model/ui.py b/src/bonsai/bonsai/bim/module/model/ui.py
index ad7de65556..86beea6079 100644
--- a/src/bonsai/bonsai/bim/module/model/ui.py
+++ b/src/bonsai/bonsai/bim/module/model/ui.py
@@ -16,8 +16,10 @@
# You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see .
+from __future__ import annotations
import bpy
import bonsai.bim
+from bonsai.bim import module
import bonsai.tool as tool
from bpy.types import Panel, Menu
from bonsai.bim.helper import prop_with_search
@@ -39,6 +41,9 @@ if TYPE_CHECKING or bpy.app.version >= (5, 0, 0):
else:
import bl_ui_utils.layout as bl_ui_utils_layout
+if TYPE_CHECKING:
+ import bonsai.bim.module.model.prop as module_prop
+
class BIM_MT_type_manager_menu(bpy.types.Menu):
bl_label = "Type Manager Menu"
@@ -664,21 +669,33 @@ class BIM_PT_external_parametric_geometry(bpy.types.Panel):
row.operator("bim.apply_external_parametric_geometry", icon="CHECKMARK", text="")
row.prop(props, "is_editing", icon="CANCEL", text="")
- row = layout.row(align=True)
- row.prop_search(props, "geo_nodes", bpy.data, "node_groups")
- if props.geo_nodes:
- assert (modifier := tool.Model.get_epg_modifier(obj))
- inputs = tool.Model.get_parametric_geometry_inputs(modifier)
- # NOTE: users won't be able to see inputs descriptions.
- # If we add group node inputs as modifiers inputs, descriptions will be visible.
- # But then we need to ensure inputs are up to date
- # (e.g. probably just by adding a refresh button).
- for input in inputs:
- row = layout.row(align=True)
- row.prop(input, "default_value", text=input.name)
+ layout.prop(props, "geometry_source")
+ if props.geometry_source == "GEONODES":
+ row = layout.row(align=True)
+ row.prop_search(props, "geo_nodes", bpy.data, "node_groups")
+ if props.geo_nodes:
+ assert (modifier := tool.Model.get_epg_modifier(obj))
+ inputs = tool.Model.get_parametric_geometry_inputs(modifier)
+ # NOTE: users won't be able to see inputs descriptions.
+ # If we add group node inputs as modifiers inputs, descriptions will be visible.
+ # But then we need to ensure inputs are up to date
+ # (e.g. probably just by adding a refresh button).
+ for input in inputs:
+ row = layout.row(align=True)
+ row.prop(input, "default_value", text=input.name)
+ elif props.geometry_source == "IFCSVERCHOK":
+ row = layout.row(align=True)
+ row.prop(props, "sverchok_nodes")
+ if props.sverchok_nodes:
+ # TODO: Updating mesh in `draw` is not ideal,
+ # should find a way to update only on graph changes.
+ res = tool.Model.update_mesh_from_sverchok(obj, props.sverchok_nodes)
+ if res is not None:
+ print(res)
+ layout.label(text=f"Error Updating from Graph, See System Console", icon="ERROR")
-def draw_door_properties(layout: bpy.types.UILayout, props: bpy.types.PropertyGroup) -> None:
+def draw_door_properties(layout: bpy.types.UILayout, props: module_prop.BIMDoorProperties) -> None:
"""Draw door properties UI (shared between properties panel and preferences)."""
# General properties
general_props = props.get_general_kwargs()
@@ -698,7 +715,7 @@ def draw_door_properties(layout: bpy.types.UILayout, props: bpy.types.PropertyGr
layout.prop(props, prop)
-def draw_window_properties(layout: bpy.types.UILayout, props: bpy.types.PropertyGroup) -> None:
+def draw_window_properties(layout: bpy.types.UILayout, props: module_prop.BIMWindowProperties) -> None:
"""Draw window properties UI (shared between properties panel and preferences)."""
number_of_panels, panels_data = props.window_types_panels[props.window_type]
@@ -734,7 +751,7 @@ def draw_window_properties(layout: bpy.types.UILayout, props: bpy.types.Property
cols[panel_i + 1].prop(props, prop, index=panel_i, text="")
-def draw_railing_properties(layout: bpy.types.UILayout, props: bpy.types.PropertyGroup) -> None:
+def draw_railing_properties(layout: bpy.types.UILayout, props: module_prop.BIMRailingProperties) -> None:
"""Draw railing properties UI (shared between properties panel and preferences)."""
general_props = props.get_general_kwargs()
for prop in general_props:
@@ -746,7 +763,7 @@ def draw_railing_properties(layout: bpy.types.UILayout, props: bpy.types.Propert
layout.prop(props, prop)
-def draw_roof_properties(layout: bpy.types.UILayout, props: bpy.types.PropertyGroup) -> None:
+def draw_roof_properties(layout: bpy.types.UILayout, props: module_prop.BIMRoofProperties) -> None:
"""Draw roof properties UI (shared between properties panel and preferences)."""
# General properties
general_props = props.get_general_kwargs()
@@ -754,7 +771,7 @@ def draw_roof_properties(layout: bpy.types.UILayout, props: bpy.types.PropertyGr
layout.prop(props, prop)
-def draw_stair_properties(layout: bpy.types.UILayout, props: bpy.types.PropertyGroup) -> None:
+def draw_stair_properties(layout: bpy.types.UILayout, props: module_prop.BIMStairProperties) -> None:
"""Draw stair properties UI (shared between properties panel and preferences)."""
for prop_name in props.get_props_kwargs():
# Skip custom_tread_lock as it's handled with custom_first_last_tread_run
diff --git a/src/bonsai/bonsai/tool/loader.py b/src/bonsai/bonsai/tool/loader.py
index 529d06a27b..d5ceea1db5 100644
--- a/src/bonsai/bonsai/tool/loader.py
+++ b/src/bonsai/bonsai/tool/loader.py
@@ -1039,7 +1039,7 @@ class Loader(bonsai.core.tool.Loader):
z_coords = [v.co.z for v in mesh.vertices]
mesh_z_min = min(z_coords)
mesh_z_max = max(z_coords)
-
+
bm = bmesh.new()
bm.from_mesh(mesh)
@@ -1068,54 +1068,54 @@ class Loader(bonsai.core.tool.Loader):
thickness_dir = -thickness_dir
no = thickness_dir
-
+
# Find start point by projecting vertices onto thickness direction
if len(mesh.vertices) > 0:
projections = [Vector(v.co).dot(no) for v in mesh.vertices]
min_proj = min(projections)
max_proj = max(projections)
-
+
centroid = sum((Vector(v.co) for v in mesh.vertices), Vector()) / len(mesh.vertices)
centroid_proj = centroid.dot(no)
-
+
if sense_factor == 1:
start_proj = min_proj
else:
start_proj = max_proj
-
+
offset_dist = start_proj - centroid_proj
co = centroid + no * offset_dist
-
+
actual_mesh_height = max_proj - min_proj
else:
co = Vector((0.0, 0.0, 0.0))
-
+
advance_direction = thickness_dir
elif usage.LayerSetDirection == "AXIS3":
# AXIS3 layers go through slab thickness (local Z)
no = Vector([0.0, 0.0, 1.0])
-
+
# Find start point by projecting vertices onto Z direction
if len(mesh.vertices) > 0:
projections = [Vector(v.co).dot(no) for v in mesh.vertices]
min_proj = min(projections)
max_proj = max(projections)
-
+
centroid = sum((Vector(v.co) for v in mesh.vertices), Vector()) / len(mesh.vertices)
centroid_proj = centroid.dot(no)
-
+
if sense_factor == 1:
start_proj = min_proj
else:
start_proj = max_proj
-
+
offset = start_proj - centroid_proj
co = centroid + no * offset
-
+
actual_mesh_height = max_proj - min_proj
else:
co = Vector((0.0, 0.0, 0.0))
-
+
advance_direction = no
elif usage.LayerSetDirection == "AXIS1":
co = Vector((0.0, 0.0, offset))
@@ -1156,13 +1156,13 @@ class Loader(bonsai.core.tool.Loader):
# Calculate scale factor
total_layer_thickness = sum(layer.LayerThickness for _, layer in layer_list)
- if 'actual_mesh_height' not in locals():
+ if "actual_mesh_height" not in locals():
actual_mesh_height = mesh_z_max - mesh_z_min if len(mesh.vertices) > 0 else total_layer_thickness
thickness_scale = actual_mesh_height / total_layer_thickness if total_layer_thickness > 0 else 1.0
last_i = len(layer_set.MaterialLayers) - 1
-
+
for idx, (original_i, layer) in enumerate(layer_list):
if idx != last_i:
prev_co = co.copy()
diff --git a/src/bonsai/bonsai/tool/model.py b/src/bonsai/bonsai/tool/model.py
index e7da203a85..2f4c4b77b7 100644
--- a/src/bonsai/bonsai/tool/model.py
+++ b/src/bonsai/bonsai/tool/model.py
@@ -54,6 +54,8 @@ T = TypeVar("T")
V_ = tool.Blender.V_
if TYPE_CHECKING:
+ import sverchok.node_tree
+ import ifcsverchok.nodes.ifc.shape_builder.shape_output
from bonsai.bim.module.model.prop import (
BIMModelProperties,
BIMDoorProperties,
@@ -2540,12 +2542,24 @@ class Model(bonsai.core.tool.Model):
@classmethod
def clean_up_parametric_geometry(cls, obj: bpy.types.Object) -> None:
+ # Geo nodes are using modifier.
modifier = tool.Model.get_epg_modifier(obj)
- assert modifier
- node_tree = modifier.node_group
- assert node_tree
- bpy.data.node_groups.remove(node_tree)
- obj.modifiers.clear()
+ if modifier is not None:
+ node_tree = modifier.node_group
+ assert node_tree
+ bpy.data.node_groups.remove(node_tree)
+ obj.modifiers.clear()
+
+ # Sverchok are changing the mesh data to preview changes.
+ # TODO: probably should use modifiers with nodes and temp mesh instead.
+ active_representation = tool.Geometry.get_active_representation(obj)
+ assert active_representation is not None
+ bonsai.core.geometry.switch_representation(
+ tool.Ifc,
+ tool.Geometry,
+ obj=obj,
+ representation=active_representation,
+ )
@classmethod
def get_parametric_geometry_inputs(cls, modifier: bpy.types.NodesModifier) -> list[bpy.types.NodeSocket]:
@@ -2557,6 +2571,51 @@ class Model(bonsai.core.tool.Model):
return [s for s in group_node.inputs if s.type != "GEOMETRY"]
+ @classmethod
+ def get_ifcsverchok_shape_output(
+ cls, node_tree: sverchok.node_tree.SverchCustomTree
+ ) -> ifcsverchok.nodes.ifc.shape_builder.shape_output.SvSbShapeOutput:
+ from ifcsverchok.nodes.ifc.shape_builder.shape_output import SvSbShapeOutput
+
+ return next(n for n in node_tree.nodes if isinstance(n, SvSbShapeOutput))
+
+ @classmethod
+ def update_mesh_from_sverchok(
+ cls, obj: bpy.types.Object, node_tree: sverchok.node_tree.SverchCustomTree
+ ) -> str | None:
+ """
+ :return: ``None`` if successful, otherwise error message.
+ """
+ import ifcsverchok.helper as helper
+
+ output_node = cls.get_ifcsverchok_shape_output(node_tree)
+ verts = helper.get_socket_value(output_node.outputs, "Vers", value_type="CONTAINER")
+ edges = helper.get_socket_value(output_node.outputs, "Edgs", value_type="CONTAINER")
+ faces = helper.get_socket_value(output_node.outputs, "Pols", value_type="CONTAINER")
+ mesh = obj.data
+ assert isinstance(mesh, bpy.types.Mesh)
+ mesh.clear_geometry()
+
+ # `shade_flat=False`, because `from_pydata` is using method that doesn't support changing shading
+ # during `Panel.draw` execution. We shade flat later ourselves.
+ mesh.from_pydata(verts, edges, faces, shade_flat=False)
+
+ def _name_convention_attribute_ensure(attributes, name, domain, data_type):
+ try:
+ attribute = attributes[name]
+ except KeyError:
+ return attributes.new(name, data_type, domain)
+ if attribute.domain == domain and attribute.data_type == data_type:
+ return attribute
+ attributes.remove(attribute)
+ return attributes.new(name, data_type, domain)
+
+ sharp_faces = _name_convention_attribute_ensure(mesh.attributes, "sharp_face", "FACE", "BOOLEAN")
+ assert isinstance(sharp_faces, bpy.types.BoolAttribute)
+ data = sharp_faces.data
+ ones = np.ones(len(data), dtype=bool)
+ data.foreach_set("value", ones)
+
@classmethod
def align_objects(
cls,
@@ -2669,3 +2728,25 @@ class Model(bonsai.core.tool.Model):
material.OffsetFromReferenceLine = custom_offset
cls.recreate_wall(element, wall)
+
+ @classmethod
+ def run_ifcsverchok_graph_on_bonsai_file(cls, node_tree: sverchok.node_tree.SverchCustomTree) -> None:
+ from ifcsverchok.ifcstore import SvIfcStore
+ from sverchok.core.update_system import UpdateTree
+
+ # We should be very careful and use bonsai file just for 1 graph update.
+ # To avoid producing duplicated data in non-ephemeral file.
+ SvIfcStore.use_bonsai_file = True
+ try:
+ # The ones below refresh asyncronously, so we're using different method to get results synchronously.
+ # - bpy.ops.node.sverchok_update_context(force_mode=True)
+ # - node_tree.force_update()
+ # TODO: Ideally we should find shape output node and update only it's furtherest children.
+ # Because user might have some nodes just floating around unused.
+ # ` update_tree = UpdateTree.get(node_tree); update_tree.add_outdated(nodes)` can be used for this.
+ UpdateTree.reset_tree(node_tree)
+ nodes_to_update = UpdateTree.main_update(node_tree)
+ # Consuming generator, which triggers the update.
+ list(nodes_to_update)
+ finally:
+ SvIfcStore.use_bonsai_file = False
diff --git a/src/ifcopenshell-python/ifcopenshell/__init__.py b/src/ifcopenshell-python/ifcopenshell/__init__.py
index 9d472d3b1d..fb38426aff 100644
--- a/src/ifcopenshell-python/ifcopenshell/__init__.py
+++ b/src/ifcopenshell-python/ifcopenshell/__init__.py
@@ -102,6 +102,7 @@ __all__ = [
"file",
"guid",
"ifcopenshell_wrapper",
+ "rocksdb_lazy_instance",
"sqlite",
"sqlite_entity",
"stream",
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/__init__.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/__init__.py
index 790125cb0b..2662015313 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/__init__.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/__init__.py
@@ -125,4 +125,5 @@ __all__ = [
"name_segments",
"register_referent_name_callback",
"update_fallback_position",
+ "get_mapped_segments",
]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_segment_to_curve.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_segment_to_curve.py
index 934e456b57..e24a946ae7 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_segment_to_curve.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_segment_to_curve.py
@@ -19,7 +19,6 @@
import numpy as np
import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.api.alignment
import ifcopenshell.geom
import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_segment_to_layout.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_segment_to_layout.py
index 999bf2f80f..70914a3353 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_segment_to_layout.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_segment_to_layout.py
@@ -17,7 +17,6 @@
# along with IfcOpenShell. If not, see .
import math
-from collections.abc import Sequence
import numpy as np
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_zero_length_segment.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_zero_length_segment.py
index 00ac9d6000..71da0d3938 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_zero_length_segment.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_zero_length_segment.py
@@ -18,7 +18,6 @@
import ifcopenshell
import ifcopenshell.api.alignment
-import ifcopenshell.util
import ifcopenshell.util.alignment
from ifcopenshell import entity_instance
from ifcopenshell.api.alignment._get_segment_start_point_label import (
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_geometric_representation.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_geometric_representation.py
index 30b91bb0a0..933ee3a470 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_geometric_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_geometric_representation.py
@@ -16,8 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import math
-from collections.abc import Sequence
import ifcopenshell
import ifcopenshell.api.alignment
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_offset_curve_representation.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_offset_curve_representation.py
index 31f0c583aa..6850013c96 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_offset_curve_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_offset_curve_representation.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import math
from collections.abc import Sequence
import ifcopenshell
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_polyline_representation.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_polyline_representation.py
index c745e6b9ac..4d31917fae 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_polyline_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_polyline_representation.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import math
from collections.abc import Sequence
import ifcopenshell
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_cant_segment.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_cant_segment.py
index 27a781c505..2abd74c189 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_cant_segment.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_cant_segment.py
@@ -16,12 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import math
-from collections.abc import Sequence
-import ifcopenshell
import ifcopenshell.api.alignment
-import ifcopenshell.api.geometry
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_segment_start_point_label.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_segment_start_point_label.py
index 34b30b9f59..6e5453489b 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_segment_start_point_label.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_segment_start_point_label.py
@@ -16,9 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-from collections.abc import Sequence
-import ifcopenshell
from ifcopenshell import entity_instance
_horizontal_callback = None
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_cant_segment.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_cant_segment.py
index e5b9ea0381..d7ae7526b4 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_cant_segment.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_cant_segment.py
@@ -21,7 +21,6 @@ from collections.abc import Sequence
import ifcopenshell
from ifcopenshell import entity_instance
-from ifcopenshell.api.alignment import get_axis_subcontext
def _get_axis(file: ifcopenshell.file, Ds: float, rail_head_distance: float) -> entity_instance:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_horizontal_segment.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_horizontal_segment.py
index 17de77a7ad..0ab7d7334b 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_horizontal_segment.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_horizontal_segment.py
@@ -21,7 +21,6 @@ from collections.abc import Sequence
import ifcopenshell
import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
-import ifcopenshell.util
import ifcopenshell.util.unit
from ifcopenshell import entity_instance
from ifcopenshell.api.alignment._get_cant_segment import _get_cant_segment
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_vertical_segment.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_vertical_segment.py
index e47a50d5ce..707cf0cba1 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_vertical_segment.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_vertical_segment.py
@@ -20,7 +20,7 @@ import math
from collections.abc import Sequence
import ifcopenshell
-from ifcopenshell import entity_instance, ifcopenshell_wrapper
+from ifcopenshell import entity_instance
def _polynomial_length(A: float, B: float, C: float, L: float) -> float:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_update_curve_segment_transition_code.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_update_curve_segment_transition_code.py
index 5e1c2d0123..367bf2e2fd 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_update_curve_segment_transition_code.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_update_curve_segment_transition_code.py
@@ -16,14 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import math
-import numpy as np
-
-import ifcopenshell
import ifcopenshell.api.alignment
-import ifcopenshell.geom
-from ifcopenshell import entity_instance, ifcopenshell_wrapper
+from ifcopenshell import entity_instance
def _update_curve_segment_transition_code(prev_segment: entity_instance, segment: entity_instance) -> None:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/add_stationing_referent.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/add_stationing_referent.py
index bccc7b0213..2d70ace789 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/add_stationing_referent.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/add_stationing_referent.py
@@ -20,7 +20,6 @@ import numpy as np
import ifcopenshell
import ifcopenshell.api.alignment
-import ifcopenshell.api.nest
import ifcopenshell.api.pset
import ifcopenshell.geom
import ifcopenshell.guid
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/add_vertical_layout.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/add_vertical_layout.py
index 41daef657c..09feb78a40 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/add_vertical_layout.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/add_vertical_layout.py
@@ -17,7 +17,6 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.api.aggregate
import ifcopenshell.api.alignment
import ifcopenshell.api.geometry
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_as_offset_curve.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_as_offset_curve.py
index f4bc35773a..b24fb16b29 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_as_offset_curve.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_as_offset_curve.py
@@ -20,9 +20,6 @@ from collections.abc import Sequence
import ifcopenshell
import ifcopenshell.api.aggregate
-import ifcopenshell.api.alignment
-import ifcopenshell.api.nest
-import ifcopenshell.util.alignment
from ifcopenshell import entity_instance
from ifcopenshell.api.alignment._create_offset_curve_representation import (
_create_offset_curve_representation,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_by_pi_method.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_by_pi_method.py
index 09a0f0ecb6..e6ceba0572 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_by_pi_method.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_by_pi_method.py
@@ -19,9 +19,7 @@
from collections.abc import Sequence
import ifcopenshell
-import ifcopenshell.api.aggregate
import ifcopenshell.api.alignment
-import ifcopenshell.api.nest
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_from_csv.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_from_csv.py
index ce7192611c..3bd8ed275d 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_from_csv.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_from_csv.py
@@ -17,13 +17,10 @@
# along with IfcOpenShell. If not, see .
import csv
-from collections.abc import Sequence
import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.api.alignment
from ifcopenshell import entity_instance
-from ifcopenshell.api.alignment import get_axis_subcontext
def create_from_csv(file: ifcopenshell.file, filepath: str) -> entity_instance:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_layout_segment.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_layout_segment.py
index 6fd6876e08..52f329694b 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_layout_segment.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_layout_segment.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import math
from typing import Union
import numpy as np
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_alignment_layout_nest.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_alignment_layout_nest.py
index b870fd1692..2a6287f6eb 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_alignment_layout_nest.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_alignment_layout_nest.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_alignment_layouts.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_alignment_layouts.py
index 4b4a1a17d3..5e05cf1fe4 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_alignment_layouts.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_alignment_layouts.py
@@ -18,9 +18,6 @@
from collections.abc import Sequence
-import ifcopenshell
-import ifcopenshell.util
-import ifcopenshell.util.representation
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_alignment_segment_nest.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_alignment_segment_nest.py
index fba39617ea..4fc732ed0c 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_alignment_segment_nest.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_alignment_segment_nest.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_basis_curve.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_basis_curve.py
index 0bf28746fe..7057640e02 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_basis_curve.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_basis_curve.py
@@ -16,8 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
-import ifcopenshell.util
import ifcopenshell.util.representation
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_child_alignments.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_child_alignments.py
index ccc8f01214..db3a74b35b 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_child_alignments.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_child_alignments.py
@@ -18,9 +18,6 @@
from collections.abc import Sequence
-import ifcopenshell
-import ifcopenshell.util
-import ifcopenshell.util.element
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_curve.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_curve.py
index 6b1a7172d9..1bf320db60 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_curve.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_curve.py
@@ -16,8 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
-import ifcopenshell.util
import ifcopenshell.util.representation
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_curve_segment_transition_code.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_curve_segment_transition_code.py
index 6711935e6f..7fe4d30513 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_curve_segment_transition_code.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_curve_segment_transition_code.py
@@ -16,12 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import math
import numpy as np
-import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.geom
from ifcopenshell import entity_instance, ifcopenshell_wrapper
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_layout_curve.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_layout_curve.py
index 0b5a70b127..4b26754ee8 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_layout_curve.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_layout_curve.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
import ifcopenshell.api.alignment
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_layout_segments.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_layout_segments.py
index 34cfd90a1d..758693081b 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_layout_segments.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_layout_segments.py
@@ -18,9 +18,6 @@
from collections.abc import Sequence
-import ifcopenshell
-import ifcopenshell.util
-import ifcopenshell.util.element
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_mapped_segments.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_mapped_segments.py
index 2e10aa9824..0b8a3b65b3 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_mapped_segments.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_mapped_segments.py
@@ -18,7 +18,6 @@
from collections.abc import Sequence
-import ifcopenshell
import ifcopenshell.api.alignment
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_parent_alignment.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_parent_alignment.py
index 333bfc01e5..d99d832fd2 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_parent_alignment.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_parent_alignment.py
@@ -16,9 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
-import ifcopenshell.util
-import ifcopenshell.util.representation
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/has_zero_length_segment.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/has_zero_length_segment.py
index 036e4de59a..7daa9f23f1 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/has_zero_length_segment.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/has_zero_length_segment.py
@@ -16,9 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
-import ifcopenshell.api.alignment
-import ifcopenshell.util.element
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/layout_horizontal_alignment_by_pi_method.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/layout_horizontal_alignment_by_pi_method.py
index ed157c3c90..676e03e429 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/layout_horizontal_alignment_by_pi_method.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/layout_horizontal_alignment_by_pi_method.py
@@ -21,7 +21,6 @@ from collections.abc import Sequence
import ifcopenshell
import ifcopenshell.api.alignment
-import ifcopenshell.util
import ifcopenshell.util.unit
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/name_segments.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/name_segments.py
index 6036332088..e010119b1a 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/name_segments.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/name_segments.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/util.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/util.py
index 144311a3df..c36e635768 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/util.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/util.py
@@ -16,17 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import math
import numpy as np
import ifcopenshell
-import ifcopenshell.api.alignment
import ifcopenshell.geom
-import ifcopenshell.guid
-import ifcopenshell.template
-import ifcopenshell.util
-import ifcopenshell.util.alignment
from ifcopenshell import entity_instance, ifcopenshell_wrapper
diff --git a/src/ifcopenshell-python/ifcopenshell/api/attribute/edit_attributes.py b/src/ifcopenshell-python/ifcopenshell/api/attribute/edit_attributes.py
index 2e679fd409..1f46e70921 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/attribute/edit_attributes.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/attribute/edit_attributes.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import sys
from types import EllipsisType
from typing import Any, Union
diff --git a/src/ifcopenshell-python/ifcopenshell/api/classification/add_classification.py b/src/ifcopenshell-python/ifcopenshell/api/classification/add_classification.py
index 6642e618b4..50cff83194 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/classification/add_classification.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/classification/add_classification.py
@@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-from typing import Any, Union
+from typing import Union
import ifcopenshell
import ifcopenshell.guid
diff --git a/src/ifcopenshell-python/ifcopenshell/api/cogo/assign_survey_point.py b/src/ifcopenshell-python/ifcopenshell/api/cogo/assign_survey_point.py
index be9e650ac7..5117998c6f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/cogo/assign_survey_point.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/cogo/assign_survey_point.py
@@ -16,9 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import typing
-import ifcopenshell
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/cogo/edit_survey_point.py b/src/ifcopenshell-python/ifcopenshell/api/cogo/edit_survey_point.py
index 3c7d478441..1ee499e026 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/cogo/edit_survey_point.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/cogo/edit_survey_point.py
@@ -16,9 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import typing
-import ifcopenshell
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/cost/calculate_cost_item_resource_value.py b/src/ifcopenshell-python/ifcopenshell/api/cost/calculate_cost_item_resource_value.py
index fc53e2ff3d..e37b597b3d 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/cost/calculate_cost_item_resource_value.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/cost/calculate_cost_item_resource_value.py
@@ -17,7 +17,6 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell.api.cost
-import ifcopenshell.util.date
import ifcopenshell.util.resource
diff --git a/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_value_formula.py b/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_value_formula.py
index 213940904d..1fd46a41c3 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_value_formula.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_value_formula.py
@@ -21,8 +21,6 @@ from typing import Any
import ifcopenshell
import ifcopenshell.api.cost
import ifcopenshell.util.cost
-import ifcopenshell.util.element
-import ifcopenshell.util.unit
def edit_cost_value_formula(file: ifcopenshell.file, cost_value: ifcopenshell.entity_instance, formula: str) -> None:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_representation.py
index d77655a60c..0a1adb1ec1 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_representation.py
@@ -28,7 +28,7 @@ from mathutils import Matrix, Vector
import ifcopenshell.util.shape_builder
import ifcopenshell.util.unit
-from ifcopenshell.util.shape_builder import VectorType, ifc_safe_vector_type
+from ifcopenshell.util.shape_builder import ifc_safe_vector_type
if TYPE_CHECKING:
import bonsai.tool as tool
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_slab_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_slab_representation.py
index d3a6daaad6..b5029dc934 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_slab_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_slab_representation.py
@@ -17,7 +17,7 @@
# along with IfcOpenShell. If not, see .
from math import cos, sin
-from typing import Any, Optional, Union
+from typing import Optional, Union
import ifcopenshell.util.element
import ifcopenshell.util.unit
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_wall_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_wall_representation.py
index 12a033429d..69f9a82fa7 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_wall_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_wall_representation.py
@@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-from math import cos, pi, sin
+from math import cos, sin
from typing import Any, Optional, Union
import ifcopenshell.util.element
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/assign_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/assign_representation.py
index 158f0152ac..a1e03ece8b 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/assign_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/assign_representation.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-from typing import Any
import ifcopenshell.api.geometry
import ifcopenshell.api.owner
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/disconnect_path.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/disconnect_path.py
index 6e04a9df73..625bfd329c 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/disconnect_path.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/disconnect_path.py
@@ -19,7 +19,6 @@
from typing import Optional
import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.util.element
diff --git a/src/ifcopenshell-python/ifcopenshell/api/grid/create_grid_axis.py b/src/ifcopenshell-python/ifcopenshell/api/grid/create_grid_axis.py
index 7500ab1f55..da01050d92 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/grid/create_grid_axis.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/grid/create_grid_axis.py
@@ -15,7 +15,7 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-from typing import Literal, Optional
+from typing import Literal
import ifcopenshell
diff --git a/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer.py b/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer.py
index cd61465326..a249106848 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer.py
@@ -15,7 +15,6 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-from typing import Optional
import ifcopenshell
diff --git a/src/ifcopenshell-python/ifcopenshell/api/layer/unassign_layer.py b/src/ifcopenshell-python/ifcopenshell/api/layer/unassign_layer.py
index 3eb0ed8fa1..1fc6b9762d 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/layer/unassign_layer.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/layer/unassign_layer.py
@@ -17,7 +17,6 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
-import ifcopenshell.util.element
def unassign_layer(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/add_library.py b/src/ifcopenshell-python/ifcopenshell/api/library/add_library.py
index debdded93a..7b144adb37 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/library/add_library.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/library/add_library.py
@@ -17,8 +17,6 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
-import ifcopenshell.util.date
-import ifcopenshell.util.schema
def add_library(file: ifcopenshell.file, name: str) -> ifcopenshell.entity_instance:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/assign_profile.py b/src/ifcopenshell-python/ifcopenshell/api/material/assign_profile.py
index 23a5a216b8..4ed83c6a92 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/material/assign_profile.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/material/assign_profile.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-from typing import Any
import ifcopenshell.util.representation
diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/unassign_material.py b/src/ifcopenshell-python/ifcopenshell/api/material/unassign_material.py
index 00a39a4120..e7e2542d12 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/material/unassign_material.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/material/unassign_material.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-from typing import Any
import ifcopenshell
import ifcopenshell.api.owner
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/add_application.py b/src/ifcopenshell-python/ifcopenshell/api/owner/add_application.py
index 8387ecf871..e2869325d5 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/add_application.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/add_application.py
@@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-from typing import Any, Optional, Union
+from typing import Optional, Union
import ifcopenshell.api
import ifcopenshell.api.owner
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/update_owner_history.py b/src/ifcopenshell-python/ifcopenshell/api/owner/update_owner_history.py
index 7df304778a..0c29c70018 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/update_owner_history.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/update_owner_history.py
@@ -20,7 +20,6 @@ import time
from typing import Union
import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.api.owner.settings
import ifcopenshell.util.element
diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset/assign_pset.py b/src/ifcopenshell-python/ifcopenshell/api/pset/assign_pset.py
index eef7f6e8e9..908ffd9aad 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/pset/assign_pset.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/pset/assign_pset.py
@@ -21,7 +21,6 @@ from typing import Union
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
-import ifcopenshell.util.element
def assign_pset(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset/unassign_pset.py b/src/ifcopenshell-python/ifcopenshell/api/pset/unassign_pset.py
index 24256f77fe..e172f7fed1 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/pset/unassign_pset.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/pset/unassign_pset.py
@@ -17,8 +17,6 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
-import ifcopenshell.api.owner
-import ifcopenshell.guid
import ifcopenshell.util.element
diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset/unshare_pset.py b/src/ifcopenshell-python/ifcopenshell/api/pset/unshare_pset.py
index 051905b2b7..d272f98495 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/pset/unshare_pset.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/pset/unshare_pset.py
@@ -17,9 +17,7 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
-import ifcopenshell.api.owner
import ifcopenshell.api.pset
-import ifcopenshell.guid
import ifcopenshell.util.element
diff --git a/src/ifcopenshell-python/ifcopenshell/api/resource/calculate_resource_usage.py b/src/ifcopenshell-python/ifcopenshell/api/resource/calculate_resource_usage.py
index 24815d45e0..5c707fc5de 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/resource/calculate_resource_usage.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/resource/calculate_resource_usage.py
@@ -16,12 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import math
import ifcopenshell.api
import ifcopenshell.util.constraint
import ifcopenshell.util.date
-import ifcopenshell.util.element
import ifcopenshell.util.resource
diff --git a/src/ifcopenshell-python/ifcopenshell/api/resource/calculate_resource_work.py b/src/ifcopenshell-python/ifcopenshell/api/resource/calculate_resource_work.py
index 0ec5f56fe4..fc597cce3a 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/resource/calculate_resource_work.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/resource/calculate_resource_work.py
@@ -18,8 +18,6 @@
import ifcopenshell.api.resource
import ifcopenshell.util.constraint
-import ifcopenshell.util.date
-import ifcopenshell.util.element
import ifcopenshell.util.resource
diff --git a/src/ifcopenshell-python/ifcopenshell/api/root/copy_class.py b/src/ifcopenshell-python/ifcopenshell/api/root/copy_class.py
index 867f25f727..f8c0efb7bb 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/root/copy_class.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/root/copy_class.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-from typing import Any
import ifcopenshell
import ifcopenshell.api.geometry
@@ -25,7 +24,6 @@ import ifcopenshell.api.root
import ifcopenshell.api.system
import ifcopenshell.util.element
import ifcopenshell.util.placement
-import ifcopenshell.util.system
def copy_class(file: ifcopenshell.file, product: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/root/create_entity.py b/src/ifcopenshell-python/ifcopenshell/api/root/create_entity.py
index 6afe5ec3a6..3179884d80 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/root/create_entity.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/root/create_entity.py
@@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-from typing import Any, Optional
+from typing import Optional
import ifcopenshell
import ifcopenshell.api.owner
diff --git a/src/ifcopenshell-python/ifcopenshell/api/root/reassign_class.py b/src/ifcopenshell-python/ifcopenshell/api/root/reassign_class.py
index c7971bc4f7..e8ed2b7173 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/root/reassign_class.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/root/reassign_class.py
@@ -24,7 +24,6 @@ import ifcopenshell.api.geometry
import ifcopenshell.api.pset
import ifcopenshell.api.spatial
import ifcopenshell.api.type
-import ifcopenshell.guid
import ifcopenshell.util.element
import ifcopenshell.util.representation
import ifcopenshell.util.schema
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_time_period.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_time_period.py
index 8a72d2044d..e10bc4ccb6 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_time_period.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_time_period.py
@@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-from datetime import datetime, time, timedelta
+from datetime import time
from typing import Optional, Union
import ifcopenshell.api
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/create_baseline.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/create_baseline.py
index f70ead281f..5a53add448 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/create_baseline.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/create_baseline.py
@@ -23,9 +23,7 @@ import ifcopenshell.api.control
import ifcopenshell.api.owner
import ifcopenshell.api.sequence
import ifcopenshell.guid
-import ifcopenshell.util.element
import ifcopenshell.util.sequence
-import ifcopenshell.util.system
def create_baseline(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/structural/assign_structural_analysis_model.py b/src/ifcopenshell-python/ifcopenshell/api/structural/assign_structural_analysis_model.py
index e378b3d984..01254d7985 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/structural/assign_structural_analysis_model.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/structural/assign_structural_analysis_model.py
@@ -20,8 +20,6 @@ from typing import Union
import ifcopenshell
import ifcopenshell.api.group
-import ifcopenshell.api.owner
-import ifcopenshell.guid
def assign_structural_analysis_model(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/structural/remove_structural_load_case.py b/src/ifcopenshell-python/ifcopenshell/api/structural/remove_structural_load_case.py
index 401db40dbc..6b381f81a1 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/structural/remove_structural_load_case.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/structural/remove_structural_load_case.py
@@ -17,7 +17,6 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.util.element
diff --git a/src/ifcopenshell-python/ifcopenshell/api/structural/remove_structural_load_group.py b/src/ifcopenshell-python/ifcopenshell/api/structural/remove_structural_load_group.py
index 25acbbe9cc..26da2d157f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/structural/remove_structural_load_group.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/structural/remove_structural_load_group.py
@@ -17,7 +17,6 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.util.element
diff --git a/src/ifcopenshell-python/ifcopenshell/api/structural/unassign_structural_analysis_model.py b/src/ifcopenshell-python/ifcopenshell/api/structural/unassign_structural_analysis_model.py
index 2053e7d075..fcb3a2ead3 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/structural/unassign_structural_analysis_model.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/structural/unassign_structural_analysis_model.py
@@ -18,8 +18,6 @@
import ifcopenshell
import ifcopenshell.api.group
-import ifcopenshell.api.owner
-import ifcopenshell.util.element
def unassign_structural_analysis_model(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/style/add_surface_textures.py b/src/ifcopenshell-python/ifcopenshell/api/style/add_surface_textures.py
index a0765bbf8d..49e1381da2 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/style/add_surface_textures.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/style/add_surface_textures.py
@@ -20,7 +20,6 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Any, Optional
import ifcopenshell
-import ifcopenshell.api
if TYPE_CHECKING:
import bpy
diff --git a/src/ifcopenshell-python/ifcopenshell/api/system/assign_port.py b/src/ifcopenshell-python/ifcopenshell/api/system/assign_port.py
index 20e2ec26b8..5422695fe5 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/system/assign_port.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/system/assign_port.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-from typing import Any
import ifcopenshell
import ifcopenshell.api.geometry
diff --git a/src/ifcopenshell-python/ifcopenshell/api/system/disconnect_port.py b/src/ifcopenshell-python/ifcopenshell/api/system/disconnect_port.py
index 8ffbfcf380..7ae790e753 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/system/disconnect_port.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/system/disconnect_port.py
@@ -17,7 +17,6 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.util.element
diff --git a/src/ifcopenshell-python/ifcopenshell/api/system/unassign_system.py b/src/ifcopenshell-python/ifcopenshell/api/system/unassign_system.py
index 2921524094..725abc6fe3 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/system/unassign_system.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/system/unassign_system.py
@@ -18,7 +18,6 @@
import ifcopenshell
import ifcopenshell.api.group
-import ifcopenshell.util.element
def unassign_system(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/type/map_type_representations.py b/src/ifcopenshell-python/ifcopenshell/api/type/map_type_representations.py
index 0c4c66ae16..5e2f7de989 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/type/map_type_representations.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/type/map_type_representations.py
@@ -18,7 +18,6 @@
import ifcopenshell
import ifcopenshell.api.geometry
-import ifcopenshell.util.element
def map_type_representations(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/unit/add_derived_unit.py b/src/ifcopenshell-python/ifcopenshell/api/unit/add_derived_unit.py
index 5cd167e66d..2c308b42d9 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/unit/add_derived_unit.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/unit/add_derived_unit.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-from typing import Any, Optional
import ifcopenshell.util.unit
diff --git a/src/ifcopenshell-python/ifcopenshell/draw.py b/src/ifcopenshell-python/ifcopenshell/draw.py
index 15ad2ef11f..5f6d761ceb 100644
--- a/src/ifcopenshell-python/ifcopenshell/draw.py
+++ b/src/ifcopenshell-python/ifcopenshell/draw.py
@@ -670,7 +670,6 @@ def main(
if __name__ == "__main__":
import argparse
- import sys
import time
times = []
diff --git a/src/ifcopenshell-python/ifcopenshell/geom/__init__.py b/src/ifcopenshell-python/ifcopenshell/geom/__init__.py
index 604e5b8e37..9ed96fa0c8 100644
--- a/src/ifcopenshell-python/ifcopenshell/geom/__init__.py
+++ b/src/ifcopenshell-python/ifcopenshell/geom/__init__.py
@@ -40,7 +40,7 @@ def _has_occ():
pass
try:
- import OCC.BRepTools
+ import OCC.BRepTools # noqa: F401
return True
except ImportError:
@@ -52,6 +52,6 @@ def _has_occ():
has_occ = _has_occ()
if has_occ:
- from . import occ_utils as utils
+ from . import occ_utils as utils # noqa: F401
from .main import *
diff --git a/src/ifcopenshell-python/ifcopenshell/geom/app.py b/src/ifcopenshell-python/ifcopenshell/geom/app.py
index 4ee0a5d482..fa07f3f2b8 100644
--- a/src/ifcopenshell-python/ifcopenshell/geom/app.py
+++ b/src/ifcopenshell-python/ifcopenshell/geom/app.py
@@ -18,7 +18,6 @@
import functools
import multiprocessing
-import operator
import os
import sys
import time
@@ -26,11 +25,10 @@ import time
import ifcopenshell.ifcopenshell_wrapper as W
try:
- from OCC.Core import AIS
+ from OCC.Core import AIS # noqa: F401
USE_OCCT_HANDLE = False
except ImportError:
- from OCC import AIS
USE_OCCT_HANDLE = True
@@ -56,7 +54,6 @@ from .code_editor_pane import code_edit
try:
from OCC.Display.pyqt5Display import qtViewer3d
except BaseException:
- import OCC.Display
try:
import OCC.Display.backend
diff --git a/src/ifcopenshell-python/ifcopenshell/geom/code_editor_pane.py b/src/ifcopenshell-python/ifcopenshell/geom/code_editor_pane.py
index ff46b67d8d..3e130debbc 100644
--- a/src/ifcopenshell-python/ifcopenshell/geom/code_editor_pane.py
+++ b/src/ifcopenshell-python/ifcopenshell/geom/code_editor_pane.py
@@ -17,7 +17,6 @@
# along with IfcOpenShell. If not, see .
import logging
-import os
import sys
from code import InteractiveConsole
@@ -30,14 +29,11 @@ except BaseException:
try:
from pyqode.core import api, modes, panels
- from pyqode.core.api import CodeEdit, ColorScheme
- from pyqode.core.panels import CheckerPanel
+ from pyqode.core.api import CodeEdit
from pyqode.python import modes as pymodes
from pyqode.python import panels as pypanels
- from pyqode.python import widgets
from pyqode.python.backend import server
- from pyqode.python.modes import PyAutoIndentMode, PythonSH
- from pyqode.python.widgets import PyInteractiveConsole
+ from pyqode.python.modes import PythonSH
has_pyqode = True
except BaseException:
diff --git a/src/ifcopenshell-python/ifcopenshell/geom/main.py b/src/ifcopenshell-python/ifcopenshell/geom/main.py
index fe31a15d84..db6deecb15 100644
--- a/src/ifcopenshell-python/ifcopenshell/geom/main.py
+++ b/src/ifcopenshell-python/ifcopenshell/geom/main.py
@@ -19,9 +19,6 @@
from __future__ import annotations
-import operator
-import os
-import sys
from collections.abc import Generator, Iterable
from typing import TYPE_CHECKING, Any, Literal, Optional, TypeVar, Union, cast, overload
diff --git a/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py b/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py
index 9abddff470..8964b2392a 100644
--- a/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py
+++ b/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py
@@ -24,7 +24,7 @@ import operator
import random
import warnings
from collections.abc import Iterable
-from typing import Any, NamedTuple, Union
+from typing import NamedTuple, Union
import OCC
from typing_extensions import assert_never
diff --git a/src/ifcopenshell-python/ifcopenshell/util/doc.py b/src/ifcopenshell-python/ifcopenshell/util/doc.py
index 9c7acf16b7..b0443f6117 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/doc.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/doc.py
@@ -19,7 +19,7 @@
import copy
import json
from pathlib import Path
-from typing import Any, Literal, Optional, TypedDict, Union
+from typing import Optional, TypedDict, Union
from typing_extensions import NotRequired
diff --git a/src/ifcopenshell-python/ifcopenshell/util/generate_pset_templates.py b/src/ifcopenshell-python/ifcopenshell/util/generate_pset_templates.py
index 87c65e2f28..681c074009 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/generate_pset_templates.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/generate_pset_templates.py
@@ -30,7 +30,6 @@ import ifcopenshell.api.project
import ifcopenshell.api.unit
import ifcopenshell.guid
import ifcopenshell.ifcopenshell_wrapper as W
-import ifcopenshell.util.attribute
if not RUN_FROM_DEV_REPO:
import shutil
diff --git a/src/ifcopenshell-python/ifcopenshell/util/selector.py b/src/ifcopenshell-python/ifcopenshell/util/selector.py
index 72ff60c0a1..abcba23a0f 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/selector.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/selector.py
@@ -17,7 +17,6 @@
# along with IfcOpenShell. If not, see .
import re
-import sys
from collections.abc import Iterable
from decimal import Decimal
from types import EllipsisType
@@ -32,7 +31,6 @@ import ifcopenshell.util
import ifcopenshell.util.attribute
import ifcopenshell.util.classification
import ifcopenshell.util.element
-import ifcopenshell.util.fm
import ifcopenshell.util.geolocation
import ifcopenshell.util.placement
import ifcopenshell.util.pset
diff --git a/src/ifcopenshell-python/ifcopenshell/util/shape.py b/src/ifcopenshell-python/ifcopenshell/util/shape.py
index 4c41eff9f9..7732412861 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/shape.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/shape.py
@@ -16,28 +16,36 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from __future__ import annotations
+
from math import cos, radians
-from typing import Literal, Optional, Union
+from typing import TYPE_CHECKING, Literal, Optional, Union
import numpy as np
import numpy.typing as npt
import shapely
import shapely.ops
-import ifcopenshell.ifcopenshell_wrapper as W
import ifcopenshell.util.element
import ifcopenshell.util.placement
import ifcopenshell.util.representation
-from ifcopenshell.geom import ShapeElementType
-from ifcopenshell.util.shape_builder import VectorType
-tol = 1e-6
-AXIS_LITERAL = Literal["X", "Y", "Z"]
-VECTOR_3D = tuple[float, float, float]
+if TYPE_CHECKING:
+ import ifcopenshell.ifcopenshell_wrapper as W
+ from ifcopenshell.geom import ShapeElementType
+ from ifcopenshell.util.shape_builder import VectorType
+
+ AXIS_LITERAL = Literal["X", "Y", "Z"]
+
+ VECTOR_3D = tuple[float, float, float]
+
+# Used only for typing, but reused by `shape.py` users.
MatrixType = npt.NDArray[np.float64]
"""`npt.NDArray[np.float64]`"""
+tol = 1e-6
+
# NOTE: See IfcGeomRepresentation.h for W.Triangulation buffer types.
# NOTE: For functions that return a single scalar ensure to use .item() to
diff --git a/src/ifcopenshell-python/ifcopenshell/util/shape_builder.py b/src/ifcopenshell-python/ifcopenshell/util/shape_builder.py
index 8c0f3d6ce9..31a067bc80 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/shape_builder.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/shape_builder.py
@@ -18,7 +18,6 @@
from __future__ import annotations
-import collections
import collections.abc
from collections.abc import Sequence
from itertools import chain
@@ -29,7 +28,6 @@ import numpy as np
import numpy.typing as npt
import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.util.element
import ifcopenshell.util.placement
import ifcopenshell.util.representation
@@ -315,7 +313,7 @@ class ShapeBuilder:
Generate an IfcIndexedPolyCurve based on the provided points.
:param points: List of 2d or 3d points
- :param closed: Whether polyline should be closed. Default is `False`
+ :param closed: Whether polyline should be closed.
:param position_offset: offset to be applied to all points
:param arc_points: Indices of the middle points for arcs. For creating an arc segment,
provide 3 points: `arc_start`, `arc_middle` and `arc_end` to `points` and add the `arc_middle`
@@ -418,8 +416,9 @@ class ShapeBuilder:
3 2
0 1
- :param size: rectangle size, could be either 2d or 3d, defaults to `(1,1)`
- :param position: rectangle position, default to `None`.
+ :param size: rectangle size, could be either 2d or 3d.
+ Use 0 for one of 3d dimensions to create 2d rectangle in 3d space.
+ :param position: rectangle position.
if `position` not specified zero-vector will be used
:return: list of rectangle coords
"""
@@ -444,9 +443,11 @@ class ShapeBuilder:
"""
Generate a rectangle polyline.
- :param size: rectangle size, could be either 2d or 3d, defaults to `(1,1)`
- :param position: rectangle position, default to `None`.
- if `position` not specified zero-vector will be used
+ :param size: rectangle.
+ :param position: rectangle position.
+
+ See ``get_rectangle_coords`` for more information.
+
:return: IfcIndexedPolyCurve
"""
return self.polyline(self.get_rectangle_coords(size, position), closed=True)
@@ -787,7 +788,7 @@ class ShapeBuilder:
"""
Create IfcAxis2Placement3D from numpy matrix.
- :param matrix: 4x4 transformation matrix, defaults to `np.eye(4)`
+ :param matrix: 4x4 transformation matrix, defaults to ``np.eye(4)``
:return: IfcAxis2Placement3D
"""
if matrix is None:
@@ -968,8 +969,8 @@ class ShapeBuilder:
def sphere(self, radius: float = 1.0, center: VectorType = (0.0, 0.0, 0.0)) -> ifcopenshell.entity_instance:
"""
- :param radius: radius of the sphere, defaults to 1.0
- :param center: sphere position, defaults to `(0.0, 0.0, 0.0)`
+ :param radius: radius of the sphere.
+ :param center: sphere position.
:return: IfcSphere
"""
@@ -1072,7 +1073,7 @@ class ShapeBuilder:
:param context: IfcGeometricRepresentationSubContext
:param items: could be a list or single curve/IfcExtrudedAreaSolid
- :param representation_type: Explicitly specified RepresentationType, defaults to `None`.
+ :param representation_type: Explicitly specified RepresentationType.
If not provided it will be guessed from the items types
:return: IfcShapeRepresentation
"""
@@ -1183,8 +1184,8 @@ class ShapeBuilder:
:param fillets: list of points from `coords` to base fillet on. Example: (1,)
:param fillet_radius: list of fillet radius for each of corresponding point form `fillets`.
Example: (5.,) Note: `fillet_radius` could be just 1 float value if it's the same for all fillets.
- :param closed: boolean whether curve should be closed (whether last point connected to first one). Default: True
- :param create_ifc_curve: create IfcIndexedPolyCurve or just return the data. Default: False
+ :param closed: boolean whether curve should be closed (whether last point connected to first one).
+ :param create_ifc_curve: create IfcIndexedPolyCurve or just return the data.
:return: (points, segments, ifc_curve) for the created simple curve
if both points in e are equally far from pt, then v1 is returned.
@@ -1463,10 +1464,10 @@ class ShapeBuilder:
:param points: list of points, assuming they form consecutive closed polyline.
:param magnitude: extrusion magnitude
- :param extrusion_vector: extrusion direction, by default it's extruding by Z+ axis
+ :param extrusion_vector: extrusion direction.
:param offset: offset from the points
- :param start_cap: if True, create start cap, by default it's True
- :param end_cap: if True, create end cap, by default it's True
+ :param start_cap: if True, create start cap.
+ :param end_cap: if True, create end cap.
:return: IfcPolygonalFaceSet
"""
diff --git a/src/ifcopenshell-python/ifcopenshell/util/unit.py b/src/ifcopenshell-python/ifcopenshell/util/unit.py
index 93d4776df0..7e4686d4e4 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/unit.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/unit.py
@@ -22,7 +22,6 @@ from math import pi
from typing import Literal, Optional, Union
import ifcopenshell
-import ifcopenshell.api.unit
import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
prefixes = {
diff --git a/src/ifcopenshell-python/pyproject.toml b/src/ifcopenshell-python/pyproject.toml
index 790891e350..9bcaeeebaa 100644
--- a/src/ifcopenshell-python/pyproject.toml
+++ b/src/ifcopenshell-python/pyproject.toml
@@ -45,3 +45,6 @@ include = ["ifcopenshell*"]
[tool.ruff]
extend = "../../pyproject.toml"
+lint.select = [
+ "F401", # unused imports
+]
diff --git a/src/ifcopenshell-python/test/api/alignment/test_add_segment_to_layout.py b/src/ifcopenshell-python/test/api/alignment/test_add_segment_to_layout.py
index 9c6503516a..90a4d97d11 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_add_segment_to_layout.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_add_segment_to_layout.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api.alignment
import ifcopenshell.api.context
diff --git a/src/ifcopenshell-python/test/api/alignment/test_add_stationing_to_alignment.py b/src/ifcopenshell-python/test/api/alignment/test_add_stationing_to_alignment.py
index 52786cb28c..4dd113ebbc 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_add_stationing_to_alignment.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_add_stationing_to_alignment.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api.alignment
import ifcopenshell.api.context
diff --git a/src/ifcopenshell-python/test/api/alignment/test_add_vertical_alignment.py b/src/ifcopenshell-python/test/api/alignment/test_add_vertical_alignment.py
index 50298717b3..5a09cd1890 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_add_vertical_alignment.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_add_vertical_alignment.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api.alignment
import ifcopenshell.api.context
diff --git a/src/ifcopenshell-python/test/api/alignment/test_create.py b/src/ifcopenshell-python/test/api/alignment/test_create.py
index e9fb2d00f3..f227bfd758 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_create.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_create.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api.alignment
import ifcopenshell.api.context
diff --git a/src/ifcopenshell-python/test/api/alignment/test_create_as_offset_curve.py b/src/ifcopenshell-python/test/api/alignment/test_create_as_offset_curve.py
index 90321574bd..0b431163bc 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_create_as_offset_curve.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_create_as_offset_curve.py
@@ -18,7 +18,6 @@
import math
-import pytest
import ifcopenshell.api.alignment
import ifcopenshell.api.unit
diff --git a/src/ifcopenshell-python/test/api/alignment/test_create_as_polyline.py b/src/ifcopenshell-python/test/api/alignment/test_create_as_polyline.py
index 8724de5e95..6e4eee9527 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_create_as_polyline.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_create_as_polyline.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api.alignment
import ifcopenshell.api.unit
diff --git a/src/ifcopenshell-python/test/api/alignment/test_create_by_pi_method.py b/src/ifcopenshell-python/test/api/alignment/test_create_by_pi_method.py
index 17a7d9b558..6da7af0690 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_create_by_pi_method.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_create_by_pi_method.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api.alignment
import ifcopenshell.api.context
diff --git a/src/ifcopenshell-python/test/api/alignment/test_create_layout_segment.py b/src/ifcopenshell-python/test/api/alignment/test_create_layout_segment.py
index 87d1ca563f..ad654ac97d 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_create_layout_segment.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_create_layout_segment.py
@@ -18,7 +18,6 @@
import math
-import pytest
import ifcopenshell.api.alignment
import ifcopenshell.api.context
diff --git a/src/ifcopenshell-python/test/api/alignment/test_create_no_geometry.py b/src/ifcopenshell-python/test/api/alignment/test_create_no_geometry.py
index a8f7c3ac06..20d5f946e8 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_create_no_geometry.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_create_no_geometry.py
@@ -16,10 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api.alignment
-import ifcopenshell.api.context
import ifcopenshell.api.unit
diff --git a/src/ifcopenshell-python/test/api/alignment/test_get_alignment.py b/src/ifcopenshell-python/test/api/alignment/test_get_alignment.py
index a7821ce213..9c7a8718e2 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_get_alignment.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_get_alignment.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api.alignment
import ifcopenshell.api.context
diff --git a/src/ifcopenshell-python/test/api/alignment/test_get_basis_curve.py b/src/ifcopenshell-python/test/api/alignment/test_get_basis_curve.py
index 659b9db343..0743fa6fd7 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_get_basis_curve.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_get_basis_curve.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api.alignment
import ifcopenshell.api.context
diff --git a/src/ifcopenshell-python/test/api/alignment/test_horizontal_layout_by_pi_method.py b/src/ifcopenshell-python/test/api/alignment/test_horizontal_layout_by_pi_method.py
index 75d46ba173..0864d5a67f 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_horizontal_layout_by_pi_method.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_horizontal_layout_by_pi_method.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api.alignment
import ifcopenshell.api.context
diff --git a/src/ifcopenshell-python/test/api/alignment/test_map_alignment_cant_segment.py b/src/ifcopenshell-python/test/api/alignment/test_map_alignment_cant_segment.py
index 2f529fb08a..c3ec6c3831 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_map_alignment_cant_segment.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_map_alignment_cant_segment.py
@@ -19,7 +19,6 @@
import pytest
import ifcopenshell.api.alignment
-import ifcopenshell.api.context
from ifcopenshell.api.alignment._map_alignment_cant_segment import (
_map_alignment_cant_segment,
)
diff --git a/src/ifcopenshell-python/test/api/alignment/test_name_segments.py b/src/ifcopenshell-python/test/api/alignment/test_name_segments.py
index 20ed746ab0..2c9b8fa2ef 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_name_segments.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_name_segments.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api.alignment
import ifcopenshell.api.context
diff --git a/src/ifcopenshell-python/test/api/alignment/test_referent_names.py b/src/ifcopenshell-python/test/api/alignment/test_referent_names.py
index d18ecf16c3..d64ea9a3ec 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_referent_names.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_referent_names.py
@@ -17,7 +17,6 @@
# along with IfcOpenShell. If not, see .
import pytest
-from pytest import fixture
import ifcopenshell.api.alignment
import ifcopenshell.api.context
diff --git a/src/ifcopenshell-python/test/api/alignment/test_update_curve_segment_transition_code.py b/src/ifcopenshell-python/test/api/alignment/test_update_curve_segment_transition_code.py
index 30803b5a59..6fc87861db 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_update_curve_segment_transition_code.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_update_curve_segment_transition_code.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api.context
import ifcopenshell.api.unit
diff --git a/src/ifcopenshell-python/test/api/alignment/test_vertical_layout_by_pi_method.py b/src/ifcopenshell-python/test/api/alignment/test_vertical_layout_by_pi_method.py
index b34e22c741..bd97d644de 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_vertical_layout_by_pi_method.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_vertical_layout_by_pi_method.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api.alignment
import ifcopenshell.api.context
diff --git a/src/ifcopenshell-python/test/api/cogo/test_add_survey_point.py b/src/ifcopenshell-python/test/api/cogo/test_add_survey_point.py
index 73d3c69105..143cb32c65 100644
--- a/src/ifcopenshell-python/test/api/cogo/test_add_survey_point.py
+++ b/src/ifcopenshell-python/test/api/cogo/test_add_survey_point.py
@@ -19,7 +19,6 @@
import pytest
import ifcopenshell.api.aggregate
-import ifcopenshell.api.alignment
import ifcopenshell.api.cogo
import ifcopenshell.api.context
diff --git a/src/ifcopenshell-python/test/api/cogo/test_assign_survey_point.py b/src/ifcopenshell-python/test/api/cogo/test_assign_survey_point.py
index e19639166f..23a61c7655 100644
--- a/src/ifcopenshell-python/test/api/cogo/test_assign_survey_point.py
+++ b/src/ifcopenshell-python/test/api/cogo/test_assign_survey_point.py
@@ -19,7 +19,6 @@
import pytest
import ifcopenshell.api.aggregate
-import ifcopenshell.api.alignment
import ifcopenshell.api.cogo
import ifcopenshell.api.context
diff --git a/src/ifcopenshell-python/test/api/cogo/test_bearing2dd.py b/src/ifcopenshell-python/test/api/cogo/test_bearing2dd.py
index 433a981ac7..199aa8a4e8 100644
--- a/src/ifcopenshell-python/test/api/cogo/test_bearing2dd.py
+++ b/src/ifcopenshell-python/test/api/cogo/test_bearing2dd.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import math
import pytest
diff --git a/src/ifcopenshell-python/test/api/cogo/test_edit_survey_point.py b/src/ifcopenshell-python/test/api/cogo/test_edit_survey_point.py
index 6b714b7342..cce8837475 100644
--- a/src/ifcopenshell-python/test/api/cogo/test_edit_survey_point.py
+++ b/src/ifcopenshell-python/test/api/cogo/test_edit_survey_point.py
@@ -19,7 +19,6 @@
import pytest
import ifcopenshell.api.aggregate
-import ifcopenshell.api.alignment
import ifcopenshell.api.cogo
import ifcopenshell.api.context
diff --git a/src/ifcopenshell-python/test/api/cost/test_remove_cost_schedule.py b/src/ifcopenshell-python/test/api/cost/test_remove_cost_schedule.py
index 5acadb9673..9b6c6824f1 100644
--- a/src/ifcopenshell-python/test/api/cost/test_remove_cost_schedule.py
+++ b/src/ifcopenshell-python/test/api/cost/test_remove_cost_schedule.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api
import ifcopenshell.api.cost
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/geometry/test_assign_representation.py b/src/ifcopenshell-python/test/api/geometry/test_assign_representation.py
index ec02c7bc27..57fb48dabe 100644
--- a/src/ifcopenshell-python/test/api/geometry/test_assign_representation.py
+++ b/src/ifcopenshell-python/test/api/geometry/test_assign_representation.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api
import ifcopenshell.api.geometry
import ifcopenshell.api.material
import ifcopenshell.api.root
diff --git a/src/ifcopenshell-python/test/api/geometry/test_unassign_representation.py b/src/ifcopenshell-python/test/api/geometry/test_unassign_representation.py
index 55fbcaefe9..e44d802e23 100644
--- a/src/ifcopenshell-python/test/api/geometry/test_unassign_representation.py
+++ b/src/ifcopenshell-python/test/api/geometry/test_unassign_representation.py
@@ -17,7 +17,6 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell.api.geometry
-import ifcopenshell.util.placement
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/group/test_add_group.py b/src/ifcopenshell-python/test/api/group/test_add_group.py
index 0c3547ce49..22eaac30c5 100644
--- a/src/ifcopenshell-python/test/api/group/test_add_group.py
+++ b/src/ifcopenshell-python/test/api/group/test_add_group.py
@@ -17,7 +17,6 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell.api.group
-import ifcopenshell.util.element
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/material/test_edit_profile_usage.py b/src/ifcopenshell-python/test/api/material/test_edit_profile_usage.py
index 478c41eb55..ae4230d29f 100644
--- a/src/ifcopenshell-python/test/api/material/test_edit_profile_usage.py
+++ b/src/ifcopenshell-python/test/api/material/test_edit_profile_usage.py
@@ -20,7 +20,6 @@ import ifcopenshell.api.context
import ifcopenshell.api.geometry
import ifcopenshell.api.material
import ifcopenshell.api.root
-import ifcopenshell.util.placement
import test.bootstrap
from ifcopenshell.util.shape_builder import ShapeBuilder
diff --git a/src/ifcopenshell-python/test/api/nest/test_assign_object.py b/src/ifcopenshell-python/test/api/nest/test_assign_object.py
index 45c4d828e3..88f8d0bb90 100644
--- a/src/ifcopenshell-python/test/api/nest/test_assign_object.py
+++ b/src/ifcopenshell-python/test/api/nest/test_assign_object.py
@@ -21,7 +21,6 @@ import pytest
import ifcopenshell.api.nest
import ifcopenshell.api.root
import ifcopenshell.util.element
-import ifcopenshell.util.placement
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/project/test_append_asset.py b/src/ifcopenshell-python/test/api/project/test_append_asset.py
index f89e4d5c89..949fc2fa5f 100644
--- a/src/ifcopenshell-python/test/api/project/test_append_asset.py
+++ b/src/ifcopenshell-python/test/api/project/test_append_asset.py
@@ -37,7 +37,6 @@ import ifcopenshell.api.unit
import ifcopenshell.util.classification
import ifcopenshell.util.element
import ifcopenshell.util.placement
-import ifcopenshell.util.unit
import test.bootstrap
from ifcopenshell.util.shape_builder import ShapeBuilder
diff --git a/src/ifcopenshell-python/test/api/pset/test_assign_pset.py b/src/ifcopenshell-python/test/api/pset/test_assign_pset.py
index e1234e8fe1..0685d1dbf0 100644
--- a/src/ifcopenshell-python/test/api/pset/test_assign_pset.py
+++ b/src/ifcopenshell-python/test/api/pset/test_assign_pset.py
@@ -17,7 +17,6 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell.api.pset
-import ifcopenshell.util.element
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/pset/test_unassign_pset.py b/src/ifcopenshell-python/test/api/pset/test_unassign_pset.py
index 58c476d74a..3ee3e85328 100644
--- a/src/ifcopenshell-python/test/api/pset/test_unassign_pset.py
+++ b/src/ifcopenshell-python/test/api/pset/test_unassign_pset.py
@@ -17,7 +17,6 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell.api.pset
-import ifcopenshell.util.element
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/pset/test_unshare_pset.py b/src/ifcopenshell-python/test/api/pset/test_unshare_pset.py
index 769294e1b5..76481b9170 100644
--- a/src/ifcopenshell-python/test/api/pset/test_unshare_pset.py
+++ b/src/ifcopenshell-python/test/api/pset/test_unshare_pset.py
@@ -17,7 +17,6 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell.api.pset
-import ifcopenshell.api.root
import ifcopenshell.guid
import ifcopenshell.util.element
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/resource/test_calculate_resource_work.py b/src/ifcopenshell-python/test/api/resource/test_calculate_resource_work.py
index 6affa8a60f..a15947a544 100644
--- a/src/ifcopenshell-python/test/api/resource/test_calculate_resource_work.py
+++ b/src/ifcopenshell-python/test/api/resource/test_calculate_resource_work.py
@@ -20,7 +20,6 @@ import ifcopenshell.api.pset
import ifcopenshell.api.resource
import ifcopenshell.api.root
import ifcopenshell.api.sequence
-import ifcopenshell.util.constraint
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/root/test_copy_class.py b/src/ifcopenshell-python/test/api/root/test_copy_class.py
index 77de023379..c8cf57c3f6 100644
--- a/src/ifcopenshell-python/test/api/root/test_copy_class.py
+++ b/src/ifcopenshell-python/test/api/root/test_copy_class.py
@@ -28,7 +28,6 @@ import ifcopenshell.api.spatial
import ifcopenshell.api.system
import ifcopenshell.api.type
import ifcopenshell.api.unit
-import ifcopenshell.util
import ifcopenshell.util.system
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/sequence/test_remove_task.py b/src/ifcopenshell-python/test/api/sequence/test_remove_task.py
index 1d1d3c1467..8395afe288 100644
--- a/src/ifcopenshell-python/test/api/sequence/test_remove_task.py
+++ b/src/ifcopenshell-python/test/api/sequence/test_remove_task.py
@@ -16,9 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
-import ifcopenshell.api
import ifcopenshell.api.nest
import ifcopenshell.api.sequence
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/sequence/test_remove_work_calendar.py b/src/ifcopenshell-python/test/api/sequence/test_remove_work_calendar.py
index 42264d1182..cadf4770db 100644
--- a/src/ifcopenshell-python/test/api/sequence/test_remove_work_calendar.py
+++ b/src/ifcopenshell-python/test/api/sequence/test_remove_work_calendar.py
@@ -16,9 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
-import ifcopenshell.api
import ifcopenshell.api.control
import ifcopenshell.api.sequence
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/sequence/test_remove_work_plan.py b/src/ifcopenshell-python/test/api/sequence/test_remove_work_plan.py
index 6f9a0ee9cf..906ea7a644 100644
--- a/src/ifcopenshell-python/test/api/sequence/test_remove_work_plan.py
+++ b/src/ifcopenshell-python/test/api/sequence/test_remove_work_plan.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api
import ifcopenshell.api.sequence
diff --git a/src/ifcopenshell-python/test/api/sequence/test_remove_work_schedule.py b/src/ifcopenshell-python/test/api/sequence/test_remove_work_schedule.py
index ea2b094364..02608e64f6 100644
--- a/src/ifcopenshell-python/test/api/sequence/test_remove_work_schedule.py
+++ b/src/ifcopenshell-python/test/api/sequence/test_remove_work_schedule.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api
import ifcopenshell.api.sequence
diff --git a/src/ifcopenshell-python/test/api/sequence/test_remove_work_time.py b/src/ifcopenshell-python/test/api/sequence/test_remove_work_time.py
index 30393c540b..207206f366 100644
--- a/src/ifcopenshell-python/test/api/sequence/test_remove_work_time.py
+++ b/src/ifcopenshell-python/test/api/sequence/test_remove_work_time.py
@@ -16,9 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
-import ifcopenshell.api
import ifcopenshell.api.sequence
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/spatial/test_unassign_container.py b/src/ifcopenshell-python/test/api/spatial/test_unassign_container.py
index efd89c990f..2a75a0c9df 100644
--- a/src/ifcopenshell-python/test/api/spatial/test_unassign_container.py
+++ b/src/ifcopenshell-python/test/api/spatial/test_unassign_container.py
@@ -19,7 +19,6 @@
import ifcopenshell.api.root
import ifcopenshell.api.spatial
import ifcopenshell.util.element
-import ifcopenshell.util.placement
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/style/test_add_surface_textures.py b/src/ifcopenshell-python/test/api/style/test_add_surface_textures.py
index 12c1711baa..aa7d011adc 100644
--- a/src/ifcopenshell-python/test/api/style/test_add_surface_textures.py
+++ b/src/ifcopenshell-python/test/api/style/test_add_surface_textures.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api.style
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/style/test_assign_material_style.py b/src/ifcopenshell-python/test/api/style/test_assign_material_style.py
index 7b7ea3df56..40e82d7ac2 100644
--- a/src/ifcopenshell-python/test/api/style/test_assign_material_style.py
+++ b/src/ifcopenshell-python/test/api/style/test_assign_material_style.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
import ifcopenshell.api.material
import ifcopenshell.api.root
import ifcopenshell.api.style
diff --git a/src/ifcopenshell-python/test/api/style/test_assign_representation_styles.py b/src/ifcopenshell-python/test/api/style/test_assign_representation_styles.py
index 157acf49da..0dbe2b51ad 100644
--- a/src/ifcopenshell-python/test/api/style/test_assign_representation_styles.py
+++ b/src/ifcopenshell-python/test/api/style/test_assign_representation_styles.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
import ifcopenshell.api.root
import ifcopenshell.api.style
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/style/test_remove_style.py b/src/ifcopenshell-python/test/api/style/test_remove_style.py
index 5b39ec655c..04faee3b25 100644
--- a/src/ifcopenshell-python/test/api/style/test_remove_style.py
+++ b/src/ifcopenshell-python/test/api/style/test_remove_style.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api.material
import ifcopenshell.api.style
diff --git a/src/ifcopenshell-python/test/api/style/test_remove_surface_style.py b/src/ifcopenshell-python/test/api/style/test_remove_surface_style.py
index 12ebf766f2..25affe54a4 100644
--- a/src/ifcopenshell-python/test/api/style/test_remove_surface_style.py
+++ b/src/ifcopenshell-python/test/api/style/test_remove_surface_style.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api.style
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/style/test_unassign_material_style.py b/src/ifcopenshell-python/test/api/style/test_unassign_material_style.py
index 919f26e3c9..6a3fad0c20 100644
--- a/src/ifcopenshell-python/test/api/style/test_unassign_material_style.py
+++ b/src/ifcopenshell-python/test/api/style/test_unassign_material_style.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
import ifcopenshell.api.material
import ifcopenshell.api.root
import ifcopenshell.api.style
diff --git a/src/ifcopenshell-python/test/api/style/test_unassign_representation_styles.py b/src/ifcopenshell-python/test/api/style/test_unassign_representation_styles.py
index ed7285b1de..45bf852947 100644
--- a/src/ifcopenshell-python/test/api/style/test_unassign_representation_styles.py
+++ b/src/ifcopenshell-python/test/api/style/test_unassign_representation_styles.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
import ifcopenshell.api.root
import ifcopenshell.api.style
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/system/test_connect_port.py b/src/ifcopenshell-python/test/api/system/test_connect_port.py
index 06d1fb7f26..53975b5fd9 100644
--- a/src/ifcopenshell-python/test/api/system/test_connect_port.py
+++ b/src/ifcopenshell-python/test/api/system/test_connect_port.py
@@ -18,7 +18,6 @@
import ifcopenshell.api.root
import ifcopenshell.api.system
-import ifcopenshell.util.system
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/system/test_disconnect_port.py b/src/ifcopenshell-python/test/api/system/test_disconnect_port.py
index 4d782414a6..1d711bdd2c 100644
--- a/src/ifcopenshell-python/test/api/system/test_disconnect_port.py
+++ b/src/ifcopenshell-python/test/api/system/test_disconnect_port.py
@@ -17,7 +17,6 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell.api.system
-import ifcopenshell.util.system
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/api/system/test_unassign_system.py b/src/ifcopenshell-python/test/api/system/test_unassign_system.py
index 7e60cbb07c..3db260b5ab 100644
--- a/src/ifcopenshell-python/test/api/system/test_unassign_system.py
+++ b/src/ifcopenshell-python/test/api/system/test_unassign_system.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api.root
import ifcopenshell.api.system
diff --git a/src/ifcopenshell-python/test/api/test_api.py b/src/ifcopenshell-python/test/api/test_api.py
index 55889cc627..7036f93528 100644
--- a/src/ifcopenshell-python/test/api/test_api.py
+++ b/src/ifcopenshell-python/test/api/test_api.py
@@ -17,13 +17,10 @@
# along with IfcOpenShell. If not, see .
from datetime import datetime
-from typing import Union
-import ifcopenshell.api
import ifcopenshell.api.control
import ifcopenshell.api.cost
import ifcopenshell.api.root
-import ifcopenshell.api.sequence
import ifcopenshell.util.element
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/geom/geometry_tests.py b/src/ifcopenshell-python/test/geom/geometry_tests.py
index f18cb3206a..744bf432fc 100644
--- a/src/ifcopenshell-python/test/geom/geometry_tests.py
+++ b/src/ifcopenshell-python/test/geom/geometry_tests.py
@@ -18,7 +18,6 @@
import numpy as np
-import ifcopenshell
import ifcopenshell.geom
import ifcopenshell.util.shape
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/geom/polyhedral_shapes.py b/src/ifcopenshell-python/test/geom/polyhedral_shapes.py
index 07ed5bf6e6..c844c961e2 100644
--- a/src/ifcopenshell-python/test/geom/polyhedral_shapes.py
+++ b/src/ifcopenshell-python/test/geom/polyhedral_shapes.py
@@ -5,7 +5,6 @@ import pytest
import ifcopenshell
import ifcopenshell.geom
-from test.bootstrap import file
@pytest.mark.parametrize("file", ["geom/polygonal-face-tessellation.ifc"], indirect=True)
diff --git a/src/ifcopenshell-python/test/geom/stats.py b/src/ifcopenshell-python/test/geom/stats.py
index 9e2a9b2985..88f9b64345 100644
--- a/src/ifcopenshell-python/test/geom/stats.py
+++ b/src/ifcopenshell-python/test/geom/stats.py
@@ -2,7 +2,6 @@ import os
import pytest
-import ifcopenshell
from ifcopenshell.geom.stats import StatsCollector
diff --git a/src/ifcopenshell-python/test/test_entity_instance.py b/src/ifcopenshell-python/test/test_entity_instance.py
index c031796b9f..cf4c050320 100644
--- a/src/ifcopenshell-python/test/test_entity_instance.py
+++ b/src/ifcopenshell-python/test/test_entity_instance.py
@@ -16,11 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
-import ifcopenshell
-import ifcopenshell.api
-import ifcopenshell.util.element
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/test_file.py b/src/ifcopenshell-python/test/test_file.py
index 062ef88b9f..c2c0aa54ea 100644
--- a/src/ifcopenshell-python/test/test_file.py
+++ b/src/ifcopenshell-python/test/test_file.py
@@ -19,8 +19,6 @@
import pytest
import ifcopenshell
-import ifcopenshell.api
-import ifcopenshell.util.element
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/test_file_inverse.py b/src/ifcopenshell-python/test/test_file_inverse.py
index d1708bc2bb..af2e0d8a31 100644
--- a/src/ifcopenshell-python/test/test_file_inverse.py
+++ b/src/ifcopenshell-python/test/test_file_inverse.py
@@ -1,13 +1,6 @@
-import gc
-import itertools
-import pprint
-import sys
-import weakref
-
import pytest
import ifcopenshell
-import ifcopenshell.api
def test_inverse_indices():
diff --git a/src/ifcopenshell-python/test/test_sql.py b/src/ifcopenshell-python/test/test_sql.py
index d0f11792c4..39cf4c2583 100644
--- a/src/ifcopenshell-python/test/test_sql.py
+++ b/src/ifcopenshell-python/test/test_sql.py
@@ -19,7 +19,6 @@
import tempfile
from pathlib import Path
-import ifcpatch
from ifcpatch.recipes import Ifc2Sql
import ifcopenshell
diff --git a/src/ifcopenshell-python/test/test_stream.py b/src/ifcopenshell-python/test/test_stream.py
index c463c3ccca..20fe67e5ec 100644
--- a/src/ifcopenshell-python/test/test_stream.py
+++ b/src/ifcopenshell-python/test/test_stream.py
@@ -18,10 +18,8 @@
from pathlib import Path
-import pytest
import ifcopenshell
-import test.bootstrap
TEST_FILE = Path(__file__).parent / "files" / "basic.ifc"
diff --git a/src/ifcopenshell-python/test/test_validate_rocksdb.py b/src/ifcopenshell-python/test/test_validate_rocksdb.py
index 6cfde4fddd..64c010938b 100644
--- a/src/ifcopenshell-python/test/test_validate_rocksdb.py
+++ b/src/ifcopenshell-python/test/test_validate_rocksdb.py
@@ -19,7 +19,6 @@
import glob
import os
import tempfile
-import time
import pytest
diff --git a/src/ifcopenshell-python/test/test_wall_opening.py b/src/ifcopenshell-python/test/test_wall_opening.py
index 812a5420e2..a08ff445be 100644
--- a/src/ifcopenshell-python/test/test_wall_opening.py
+++ b/src/ifcopenshell-python/test/test_wall_opening.py
@@ -27,7 +27,6 @@ from dataclasses import dataclass, field
import pytest
-import ifcopenshell
import ifcopenshell.guid
import ifcopenshell.template
diff --git a/src/ifcopenshell-python/test/util/scripts/test_validate_stub.py b/src/ifcopenshell-python/test/util/scripts/test_validate_stub.py
index 82b9e02adc..a4a0b1ecbc 100644
--- a/src/ifcopenshell-python/test/util/scripts/test_validate_stub.py
+++ b/src/ifcopenshell-python/test/util/scripts/test_validate_stub.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.util.scripts.validate_stub as subject
diff --git a/src/ifcopenshell-python/test/util/test_attribute.py b/src/ifcopenshell-python/test/util/test_attribute.py
index 4b04e8a678..c3d882dc72 100644
--- a/src/ifcopenshell-python/test/util/test_attribute.py
+++ b/src/ifcopenshell-python/test/util/test_attribute.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell
import ifcopenshell.ifcopenshell_wrapper as W
diff --git a/src/ifcopenshell-python/test/util/test_brick.py b/src/ifcopenshell-python/test/util/test_brick.py
index d0cffeaba9..88302a2170 100644
--- a/src/ifcopenshell-python/test/util/test_brick.py
+++ b/src/ifcopenshell-python/test/util/test_brick.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.api.root
import ifcopenshell.api.type
diff --git a/src/ifcopenshell-python/test/util/test_date.py b/src/ifcopenshell-python/test/util/test_date.py
index dd47244ba7..9b1713a772 100644
--- a/src/ifcopenshell-python/test/util/test_date.py
+++ b/src/ifcopenshell-python/test/util/test_date.py
@@ -16,10 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell.util.date as subject
-import test.bootstrap
class TestReadableIFCDuration:
diff --git a/src/ifcopenshell-python/test/util/test_file.py b/src/ifcopenshell-python/test/util/test_file.py
index b7b34cd097..a1ee333b6b 100644
--- a/src/ifcopenshell-python/test/util/test_file.py
+++ b/src/ifcopenshell-python/test/util/test_file.py
@@ -20,7 +20,6 @@ import tempfile
import zipfile
from pathlib import Path
-import pytest
import ifcopenshell.util.file as subject
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/util/test_placement.py b/src/ifcopenshell-python/test/util/test_placement.py
index 8a26c52ee5..bd611db36b 100644
--- a/src/ifcopenshell-python/test/util/test_placement.py
+++ b/src/ifcopenshell-python/test/util/test_placement.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
import ifcopenshell.util.placement as subject
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/util/test_pset.py b/src/ifcopenshell-python/test/util/test_pset.py
index ccfbcc4970..3b44951ec4 100644
--- a/src/ifcopenshell-python/test/util/test_pset.py
+++ b/src/ifcopenshell-python/test/util/test_pset.py
@@ -17,7 +17,6 @@
# along with IfcOpenShell. If not, see .
"""Run this test from src/ifcopenshell-python folder: pytest --durations=0 ifcopenshell/util/test_pset.py"""
-from ifcopenshell import util
from ifcopenshell.util import pset
from ifcopenshell.util.pset import ApplicableEntity
diff --git a/src/ifcopenshell-python/test/util/test_selector.py b/src/ifcopenshell-python/test/util/test_selector.py
index e4de678529..0b90f3b278 100644
--- a/src/ifcopenshell-python/test/util/test_selector.py
+++ b/src/ifcopenshell-python/test/util/test_selector.py
@@ -26,13 +26,11 @@ import ifcopenshell.api.group
import ifcopenshell.api.material
import ifcopenshell.api.pset
import ifcopenshell.api.root
-import ifcopenshell.api.sequence
import ifcopenshell.api.spatial
import ifcopenshell.api.type
import ifcopenshell.api.unit
import ifcopenshell.util.element
import ifcopenshell.util.placement
-import ifcopenshell.util.pset
import ifcopenshell.util.selector as subject
import test.bootstrap
diff --git a/src/ifcopenshell-python/test/util/test_shape_builder.py b/src/ifcopenshell-python/test/util/test_shape_builder.py
index 87499b3288..5ff8adc03f 100644
--- a/src/ifcopenshell-python/test/util/test_shape_builder.py
+++ b/src/ifcopenshell-python/test/util/test_shape_builder.py
@@ -22,9 +22,7 @@ from typing import Any, Union
import numpy as np
import pytest
-import ifcopenshell.api
import ifcopenshell.geom
-import ifcopenshell.util
import ifcopenshell.util.shape
import test.bootstrap
from ifcopenshell.util.shape_builder import (
diff --git a/src/ifcopenshell-python/test/util/test_type.py b/src/ifcopenshell-python/test/util/test_type.py
index 54f0e6da16..dfc16e3446 100644
--- a/src/ifcopenshell-python/test/util/test_type.py
+++ b/src/ifcopenshell-python/test/util/test_type.py
@@ -16,9 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
-import ifcopenshell.api
import ifcopenshell.util.type as subject
import test.bootstrap
diff --git a/src/ifcsverchok/__init__.py b/src/ifcsverchok/__init__.py
index 660ea6f707..4594d8a367 100644
--- a/src/ifcsverchok/__init__.py
+++ b/src/ifcsverchok/__init__.py
@@ -81,7 +81,7 @@ ensure_addons_are_enabled("bonsai", "sverchok")
from sverchok.ui.nodeview_space_menu import add_node_menu
-def nodes_index():
+def nodes_index() -> list[tuple[str, list[tuple[str, str]]]]:
return [
(
"IFC",
@@ -111,15 +111,25 @@ def nodes_index():
("ifc.create_project", "SvIfcCreateProject"),
("ifc.quick_project_setup", "SvIfcQuickProjectSetup"),
],
- )
+ ),
+ (
+ "IFC Shape Builder",
+ [
+ ("ifc.shape_builder.rectangle", "SvIfcSbRectangle"),
+ ("ifc.shape_builder.extrude", "SvIfcSbExtrude"),
+ ("ifc.shape_builder.representation", "SvIfcSbRepresentation"),
+ ("ifc.shape_builder.test", "SvIfcSbTest"),
+ ("ifc.shape_builder.shape_output", "SvSbShapeOutput"),
+ ],
+ ),
]
def make_node_categories() -> list[dict[str, list[str]]]:
- node_categories = [{}]
+ node_categories: list[dict[str, list[str]]] = []
for category, nodes in nodes_index():
nodes = [node_name for idname, node_name in nodes]
- node_categories[0][category] = nodes
+ node_categories.append({category: nodes})
return node_categories
@@ -144,7 +154,6 @@ reload_event = False
from os.path import splitext
import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.api.aggregate
import ifcopenshell.api.root
import ifcopenshell.api.spatial
@@ -156,11 +165,11 @@ from ifcsverchok.ifcstore import SvIfcStore
class IFC_Sv_UpdateCurrent(bpy.types.Operator):
"""Update current Sverchok node tree.
- Will reset transient IFC file.
- """
+ Will reset transient IFC file"""
bl_idname = "ifc.sverchok_update_current"
bl_label = "Update Current Node Tree"
+ # bl_description = "Update current Sverchok node tree, resetting transient IFC file."
bl_options = {"REGISTER", "UNDO", "INTERNAL"}
node_group: bpy.props.StringProperty(default="")
@@ -287,11 +296,13 @@ class IFC_PT_write_file_panel(bpy.types.Panel):
def draw(self, context):
ng = context.space_data.node_tree
layout = self.layout
+ assert layout
row = layout.split(factor=0.2, align=True)
row = layout.row()
row2 = layout.row()
row.operator("ifc.sverchok_update_current", text="IFC Re-run all nodes")
row2.operator("ifc.write_file_panel")
+ layout.operator("bim.ifcsverchok_use_bonsai_file")
CLASSES = [IFC_Sv_UpdateCurrent, IFC_Sv_write_file, IFC_PT_write_file_panel]
diff --git a/src/ifcsverchok/helper.py b/src/ifcsverchok/helper.py
index d20626f365..8f9bda0c97 100644
--- a/src/ifcsverchok/helper.py
+++ b/src/ifcsverchok/helper.py
@@ -16,12 +16,14 @@
# You should have received a copy of the GNU General Public License
# along with IfcSverchok. If not, see .
-from typing import Any, TypeVar, Union
+from typing import Any, Literal, TypeVar, Union
import bpy
import ifcopenshell
import sverchok.core.sockets
-from sverchok.data_structure import zip_long_repeat
+from sverchok.data_structure import flatten_data, zip_long_repeat
+
+from ifcsverchok.ifcstore import SvIfcStore
T_socket = TypeVar("T_socket", bound=sverchok.core.sockets.SvSocketCommon)
@@ -67,6 +69,34 @@ def get_selected_nodes() -> list[bpy.types.Node]:
return [n for n in node_tree.nodes if n.select]
+def get_socket_value(
+ sockets: Union[bpy.types.NodeInputs, bpy.types.NodeOutputs],
+ name: str,
+ *,
+ value_type: Literal["SINGLE_VALUE", "CONTAINER", "FLATTEN"] = "SINGLE_VALUE",
+) -> Any:
+ value = sockets[name].sv_get()
+ if value_type == "FLATTEN":
+ return flatten_data(value)
+ value = value[0]
+ if value_type == "SINGLE_VALUE":
+ return value[0]
+ return value
+
+
+def set_socket_value(
+ sockets: bpy.types.NodeOutputs,
+ name: str,
+ value: Any,
+ *,
+ value_type: Literal["SINGLE_VALUE", "FINAL_VALUE"] = "SINGLE_VALUE",
+) -> None:
+ if value_type == "SINGLE_VALUE":
+ sockets[name].sv_set([[value]])
+ return
+ sockets[name].sv_set(value)
+
+
def create_socket(
inputs_or_outputs: Union[bpy.types.NodeInputs, bpy.types.NodeOutputs],
name: str,
@@ -87,3 +117,7 @@ def create_socket(
if prop_name:
socket.prop_name = prop_name
return socket
+
+
+def get_file() -> ifcopenshell.file:
+ return SvIfcStore.get_file()
diff --git a/src/ifcsverchok/ifcstore.py b/src/ifcsverchok/ifcstore.py
index 6fda9b2cea..30cd760b87 100644
--- a/src/ifcsverchok/ifcstore.py
+++ b/src/ifcsverchok/ifcstore.py
@@ -18,9 +18,9 @@
from typing import Any, Union
+import bonsai.tool as tool
import bpy
import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.api.context
import ifcopenshell.util.representation
from ifcopenshell import template
@@ -50,6 +50,8 @@ class SvIfcStore:
future = []
schema_identifiers = ["IFC4", "IFC2X3"]
+ use_bonsai_file = False
+
@staticmethod
def purge() -> None:
SvIfcStore.path = ""
@@ -95,6 +97,8 @@ class SvIfcStore:
@staticmethod
def get_file() -> ifcopenshell.file:
+ if SvIfcStore.use_bonsai_file:
+ return tool.Ifc.get()
if SvIfcStore.file is None:
SvIfcStore.create_boilerplate()
return SvIfcStore.file
diff --git a/src/ifcsverchok/nodes/ifc/add_pset.py b/src/ifcsverchok/nodes/ifc/add_pset.py
index 3cd25cd4dc..5676dadf71 100644
--- a/src/ifcsverchok/nodes/ifc/add_pset.py
+++ b/src/ifcsverchok/nodes/ifc/add_pset.py
@@ -20,7 +20,6 @@ import json
import bpy
import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.api.pset
import sverchok.core.sockets
from bpy.props import StringProperty
diff --git a/src/ifcsverchok/nodes/ifc/add_spatial_element.py b/src/ifcsverchok/nodes/ifc/add_spatial_element.py
index f53dc3fa16..0f03dc1b52 100644
--- a/src/ifcsverchok/nodes/ifc/add_spatial_element.py
+++ b/src/ifcsverchok/nodes/ifc/add_spatial_element.py
@@ -19,8 +19,6 @@
from itertools import chain
import bpy
-import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.api.aggregate
import ifcopenshell.api.root
import ifcopenshell.api.spatial
diff --git a/src/ifcsverchok/nodes/ifc/api.py b/src/ifcsverchok/nodes/ifc/api.py
index ce75275db4..4c53b3968d 100644
--- a/src/ifcsverchok/nodes/ifc/api.py
+++ b/src/ifcsverchok/nodes/ifc/api.py
@@ -20,10 +20,9 @@ import logging
from typing import Any, Union
import bpy
-import ifcopenshell
import ifcopenshell.api
import sverchok.core.sockets
-from bpy.props import EnumProperty, StringProperty
+from bpy.props import StringProperty
from sverchok.data_structure import updateNode
from sverchok.node_tree import SverchCustomTreeNode
diff --git a/src/ifcsverchok/nodes/ifc/bmesh_to_ifc.py b/src/ifcsverchok/nodes/ifc/bmesh_to_ifc.py
index 8d623ffe1e..785d5db718 100644
--- a/src/ifcsverchok/nodes/ifc/bmesh_to_ifc.py
+++ b/src/ifcsverchok/nodes/ifc/bmesh_to_ifc.py
@@ -16,36 +16,20 @@
# You should have received a copy of the GNU General Public License
# along with IfcSverchok. If not, see .
-from copy import deepcopy
-from decimal import Context
-from email.policy import default
-from itertools import chain, cycle
-
-import bonsai.core.geometry as core
-import bonsai.tool as tool
import bpy
import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.api.context
import ifcopenshell.api.geometry
import ifcopenshell.util.representation
-from bonsai.bim.module.root.prop import get_contexts
from bpy.props import (
BoolProperty,
EnumProperty,
- IntProperty,
PointerProperty,
StringProperty,
)
from mathutils import Matrix
-from sverchok.core.socket_data import sv_get_socket
from sverchok.data_structure import (
- fixed_iter,
- flat_iter,
- flatten_data,
- node_id,
updateNode,
- zip_long_repeat,
)
from sverchok.node_tree import SverchCustomTreeNode
diff --git a/src/ifcsverchok/nodes/ifc/by_guid.py b/src/ifcsverchok/nodes/ifc/by_guid.py
index 029b1b11a5..fd6b79bb55 100644
--- a/src/ifcsverchok/nodes/ifc/by_guid.py
+++ b/src/ifcsverchok/nodes/ifc/by_guid.py
@@ -19,7 +19,6 @@
import itertools
import bpy
-import ifcopenshell
from bpy.props import StringProperty
from sverchok.data_structure import flatten_data, updateNode
from sverchok.node_tree import SverchCustomTreeNode
diff --git a/src/ifcsverchok/nodes/ifc/by_query.py b/src/ifcsverchok/nodes/ifc/by_query.py
index 1bdd88054a..6b6cb12bdb 100644
--- a/src/ifcsverchok/nodes/ifc/by_query.py
+++ b/src/ifcsverchok/nodes/ifc/by_query.py
@@ -17,24 +17,35 @@
# along with IfcSverchok. If not, see .
import bpy
-import ifcopenshell
import ifcopenshell.util.selector
from bpy.props import StringProperty
from sverchok.data_structure import updateNode
from sverchok.node_tree import SverchCustomTreeNode
-import ifcsverchok.helper
+import ifcsverchok.helper as helper
from ifcsverchok.ifcstore import SvIfcStore
-class SvIfcByQuery(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
+class SvIfcByQuery(bpy.types.Node, SverchCustomTreeNode, helper.SvIfcCore):
bl_idname = "SvIfcByQuery"
bl_label = "IFC By Query"
query: StringProperty(name="Query", update=updateNode)
- def sv_init(self, context):
- self.inputs.new("SvStringsSocket", "query").prop_name = "query"
- self.outputs.new("SvStringsSocket", "Entity")
+ def sv_init(self, context) -> None:
+ helper.create_socket(
+ self.inputs,
+ "query",
+ description="IFC Query string.",
+ data_type="list[list[str]]",
+ prop_name="query",
+ )
+ helper.create_socket(
+ self.outputs,
+ "Entity",
+ description="IFC Entities found by the query.",
+ data_type="set[ifcopenshell.entity_instance]",
+ prop_name="Entity",
+ )
def process(self):
if not self.inputs["query"].sv_get()[0][0]:
@@ -44,8 +55,8 @@ class SvIfcByQuery(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIf
super().process()
def process_ifc(self, query: str) -> None:
- selector = ifcopenshell.util.selector.Selector()
- self.outputs["Entity"].sv_set([selector.parse(self.file, query)])
+ elements = ifcopenshell.util.selector.filter_elements(self.file, query)
+ self.outputs["Entity"].sv_set(elements)
def register():
diff --git a/src/ifcsverchok/nodes/ifc/create_entity.py b/src/ifcsverchok/nodes/ifc/create_entity.py
index bc63b3bc08..2ce1d54461 100644
--- a/src/ifcsverchok/nodes/ifc/create_entity.py
+++ b/src/ifcsverchok/nodes/ifc/create_entity.py
@@ -17,8 +17,6 @@
# along with IfcSverchok. If not, see .
import bpy
-import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.api.geometry
import ifcopenshell.api.root
import ifcopenshell.util.schema
diff --git a/src/ifcsverchok/nodes/ifc/create_project.py b/src/ifcsverchok/nodes/ifc/create_project.py
index 4f0b19a398..b6de31de34 100644
--- a/src/ifcsverchok/nodes/ifc/create_project.py
+++ b/src/ifcsverchok/nodes/ifc/create_project.py
@@ -18,7 +18,6 @@
import bpy
import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.api.context
import ifcopenshell.api.root
import ifcopenshell.api.unit
diff --git a/src/ifcsverchok/nodes/ifc/create_shape.py b/src/ifcsverchok/nodes/ifc/create_shape.py
index 7b94008952..de47c3b0e6 100644
--- a/src/ifcsverchok/nodes/ifc/create_shape.py
+++ b/src/ifcsverchok/nodes/ifc/create_shape.py
@@ -20,9 +20,8 @@ import logging
import bonsai.bim.import_ifc
import bpy
-import ifcopenshell
import ifcopenshell.geom
-from bpy.props import BoolProperty, PointerProperty, StringProperty
+from bpy.props import BoolProperty, StringProperty
from sverchok.data_structure import flatten_data, updateNode
from sverchok.node_tree import SverchCustomTreeNode
@@ -102,10 +101,8 @@ class SvIfcCreateShape(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.
def register():
- # bpy.utils.register_class(SvIfcCreateShapeRefresh)
bpy.utils.register_class(SvIfcCreateShape)
def unregister():
bpy.utils.unregister_class(SvIfcCreateShape)
- # bpy.utils.unregister_class(SvIfcCreateShapeRefresh)
diff --git a/src/ifcsverchok/nodes/ifc/generate_guid.py b/src/ifcsverchok/nodes/ifc/generate_guid.py
index 26f50e8ae6..759dcbb90e 100644
--- a/src/ifcsverchok/nodes/ifc/generate_guid.py
+++ b/src/ifcsverchok/nodes/ifc/generate_guid.py
@@ -17,7 +17,6 @@
# along with IfcSverchok. If not, see .
import bpy
-import ifcopenshell
import ifcopenshell.guid
from sverchok.node_tree import SverchCustomTreeNode
diff --git a/src/ifcsverchok/nodes/ifc/get_attribute.py b/src/ifcsverchok/nodes/ifc/get_attribute.py
index e809500de3..7f90e742a8 100644
--- a/src/ifcsverchok/nodes/ifc/get_attribute.py
+++ b/src/ifcsverchok/nodes/ifc/get_attribute.py
@@ -17,8 +17,6 @@
# along with IfcSverchok. If not, see .
import bpy
-import ifcopenshell
-import ifcopenshell.util.element
from bpy.props import StringProperty
from sverchok.data_structure import flatten_data, updateNode
from sverchok.node_tree import SverchCustomTreeNode
diff --git a/src/ifcsverchok/nodes/ifc/get_property.py b/src/ifcsverchok/nodes/ifc/get_property.py
index f99dff7aa3..e8af45d606 100644
--- a/src/ifcsverchok/nodes/ifc/get_property.py
+++ b/src/ifcsverchok/nodes/ifc/get_property.py
@@ -17,7 +17,6 @@
# along with IfcSverchok. If not, see .
import bpy
-import ifcopenshell
import ifcopenshell.util.element
from bpy.props import StringProperty
from sverchok.data_structure import flatten_data, updateNode
diff --git a/src/ifcsverchok/nodes/ifc/quick_project_setup.py b/src/ifcsverchok/nodes/ifc/quick_project_setup.py
index 5787e29187..c98e80a5c4 100644
--- a/src/ifcsverchok/nodes/ifc/quick_project_setup.py
+++ b/src/ifcsverchok/nodes/ifc/quick_project_setup.py
@@ -16,11 +16,7 @@
# You should have received a copy of the GNU General Public License
# along with IfcSverchok. If not, see .
-
-from email.mime import application
-
import bpy
-import ifcopenshell
import sverchok.core.sockets
from bpy.props import StringProperty
from ifcopenshell import template
diff --git a/src/ifcsverchok/nodes/ifc/read_entity.py b/src/ifcsverchok/nodes/ifc/read_entity.py
index 38a703151d..454293e7d3 100644
--- a/src/ifcsverchok/nodes/ifc/read_entity.py
+++ b/src/ifcsverchok/nodes/ifc/read_entity.py
@@ -19,7 +19,7 @@
import bpy
import ifcopenshell
from bpy.props import StringProperty
-from sverchok.data_structure import ensure_min_nesting, flatten_data, updateNode
+from sverchok.data_structure import flatten_data, updateNode
from sverchok.node_tree import SverchCustomTreeNode
import ifcsverchok.helper
diff --git a/src/ifcsverchok/nodes/ifc/select_blender_objects.py b/src/ifcsverchok/nodes/ifc/select_blender_objects.py
index 3a0053a514..d2582dcaff 100644
--- a/src/ifcsverchok/nodes/ifc/select_blender_objects.py
+++ b/src/ifcsverchok/nodes/ifc/select_blender_objects.py
@@ -19,7 +19,6 @@
import bonsai.tool as tool
import bpy
import ifcopenshell
-import ifcopenshell.util.selector
from bpy.props import StringProperty
from sverchok.data_structure import updateNode
from sverchok.node_tree import SverchCustomTreeNode
diff --git a/src/ifcsverchok/nodes/ifc/shape_builder/extrude.py b/src/ifcsverchok/nodes/ifc/shape_builder/extrude.py
new file mode 100644
index 0000000000..3b984dd4d7
--- /dev/null
+++ b/src/ifcsverchok/nodes/ifc/shape_builder/extrude.py
@@ -0,0 +1,92 @@
+# IfcSverchok - IFC Sverchok extension
+# Copyright (C) 2022 Martina Jakubowska
+#
+# This file is part of IfcSverchok.
+#
+# IfcSverchok is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# IfcSverchok is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with IfcSverchok. If not, see .
+
+from typing import TYPE_CHECKING, Literal
+
+import bpy
+import ifcopenshell
+from ifcopenshell.util.shape_builder import ShapeBuilder
+from sverchok.data_structure import updateNode
+from sverchok.node_tree import SverchCustomTreeNode
+
+import ifcsverchok.helper
+import ifcsverchok.helper as helper
+
+
+class SvIfcSbExtrude(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
+ bl_idname = "SvIfcSbExtrude"
+ bl_label = "IFC Extrude"
+
+ extrude_axis: bpy.props.EnumProperty( # pyright: ignore[reportRedeclaration]
+ default="Z",
+ items=[
+ ("X", "X", "Interpret curve as in XY plane and extrude along X+."),
+ ("Y", "Y", "Interpret curve as in XZ plane and extrude along Y+."),
+ ("Z", "Z", "Interpret curve as in XY plane and extrude along Z+."),
+ ],
+ name="Extrude Axis",
+ update=updateNode,
+ )
+
+ if TYPE_CHECKING:
+ extrude_axis: Literal["X", "Y", "Z"]
+
+ def sv_init(self, context):
+ helper.create_socket(
+ self.inputs,
+ "Curve",
+ description="Curve to extrude",
+ data_type="list[list[ifcopenshell.entity_instance]]",
+ )
+ helper.create_socket(
+ self.inputs,
+ "Magnitude",
+ data_type="list[list[float]]",
+ )
+ helper.create_socket(
+ self.inputs,
+ "Position",
+ data_type="list[list[tuple[float, float, float]]]",
+ )
+ helper.create_socket(
+ self.outputs,
+ "Extruded Profile",
+ description="Extruded Profile",
+ data_type="list[list[ifcopenshell.entity_instance]]",
+ )
+
+ def draw_buttons(self, context, layout):
+ layout.prop(self, "extrude_axis")
+
+ def process(self):
+ self.file = helper.get_file()
+ curve: ifcopenshell.entity_instance = helper.get_socket_value(self.inputs, "Curve")
+ magnitude: float = helper.get_socket_value(self.inputs, "Magnitude")
+ position: tuple[float, float, float] = helper.get_socket_value(self.inputs, "Position")
+ builder = ShapeBuilder(self.file)
+ axis_kargs = builder.extrude_kwargs(self.extrude_axis)
+ extrude = builder.extrude(curve, magnitude=magnitude, position=position, **axis_kargs)
+ helper.set_socket_value(self.outputs, "Extruded Profile", extrude)
+
+
+def register():
+ bpy.utils.register_class(SvIfcSbExtrude)
+
+
+def unregister():
+ bpy.utils.unregister_class(SvIfcSbExtrude)
diff --git a/src/ifcsverchok/nodes/ifc/shape_builder/rectangle.py b/src/ifcsverchok/nodes/ifc/shape_builder/rectangle.py
new file mode 100644
index 0000000000..8b9b60c81d
--- /dev/null
+++ b/src/ifcsverchok/nodes/ifc/shape_builder/rectangle.py
@@ -0,0 +1,57 @@
+# IfcSverchok - IFC Sverchok extension
+# Copyright (C) 2022 Martina Jakubowska
+#
+# This file is part of IfcSverchok.
+#
+# IfcSverchok is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# IfcSverchok is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with IfcSverchok. If not, see .
+
+import bpy
+from ifcopenshell.util.shape_builder import ShapeBuilder
+from sverchok.node_tree import SverchCustomTreeNode
+
+import ifcsverchok.helper
+import ifcsverchok.helper as helper
+
+
+class SvIfcSbRectangle(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
+ bl_idname = "SvIfcSbRectangle"
+ bl_label = "IFC Rectangle"
+
+ def sv_init(self, context):
+ helper.create_socket(
+ self.inputs,
+ "Size (2D)",
+ data_type="list[list[tuple[float, float]]]",
+ )
+ helper.create_socket(
+ self.outputs,
+ "Rectangle",
+ description="Rectangle",
+ data_type="list[list[ifcopenshell.entity_instance]]",
+ )
+
+ def process(self):
+ file = helper.get_file()
+ builder = ShapeBuilder(file)
+ size: tuple[float, ...] = helper.get_socket_value(self.inputs, "Size", value_type="CONTAINER")
+ rectangle = builder.rectangle(size=size)
+ helper.set_socket_value(self.outputs, "Rectangle", rectangle)
+
+
+def register():
+ bpy.utils.register_class(SvIfcSbRectangle)
+
+
+def unregister():
+ bpy.utils.unregister_class(SvIfcSbRectangle)
diff --git a/src/ifcsverchok/nodes/ifc/shape_builder/representation.py b/src/ifcsverchok/nodes/ifc/shape_builder/representation.py
new file mode 100644
index 0000000000..c1e8a9eb54
--- /dev/null
+++ b/src/ifcsverchok/nodes/ifc/shape_builder/representation.py
@@ -0,0 +1,64 @@
+# IfcSverchok - IFC Sverchok extension
+# Copyright (C) 2022 Martina Jakubowska
+#
+# This file is part of IfcSverchok.
+#
+# IfcSverchok is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# IfcSverchok is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with IfcSverchok. If not, see .
+
+import bpy
+import ifcopenshell
+import ifcopenshell.util.representation
+from ifcopenshell.util.shape_builder import ShapeBuilder
+from sverchok.node_tree import SverchCustomTreeNode
+
+import ifcsverchok.helper
+import ifcsverchok.helper as helper
+
+
+class SvIfcSbRepresentation(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
+ bl_idname = "SvIfcSbRepresentation"
+ bl_label = "IFC Representation"
+
+ def sv_init(self, context):
+ helper.create_socket(
+ self.inputs,
+ "Representation Item",
+ description="Representation Item",
+ data_type="list[list[ifcopenshell.entity_instance]]",
+ )
+ helper.create_socket(
+ self.outputs,
+ "Shape Representation",
+ description="IfcShapeRepresentation",
+ data_type="list[list[ifcopenshell.entity_instance]]",
+ )
+
+ def process(self):
+ self.file = helper.get_file()
+ representation_items: list[ifcopenshell.entity_instance]
+ representation_items = helper.get_socket_value(self.inputs, "Representation Item", value_type="FLATTEN")
+
+ builder = ShapeBuilder(self.file)
+ context = ifcopenshell.util.representation.get_context(self.file, "Model", "Body", "MODEL_VIEW")
+ assert context is not None
+ representation = builder.get_representation(context, items=representation_items)
+ helper.set_socket_value(self.outputs, "Shape Representation", representation)
+
+
+def register():
+ bpy.utils.register_class(SvIfcSbRepresentation)
+
+
+def unregister():
+ bpy.utils.unregister_class(SvIfcSbRepresentation)
diff --git a/src/ifcsverchok/nodes/ifc/shape_builder/shape_output.py b/src/ifcsverchok/nodes/ifc/shape_builder/shape_output.py
new file mode 100644
index 0000000000..c3555c25e4
--- /dev/null
+++ b/src/ifcsverchok/nodes/ifc/shape_builder/shape_output.py
@@ -0,0 +1,67 @@
+# IfcSverchok - IFC Sverchok extension
+# Copyright (C) 2022 Martina Jakubowska
+#
+# This file is part of IfcSverchok.
+#
+# IfcSverchok is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# IfcSverchok is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with IfcSverchok. If not, see .
+
+import bpy
+import ifcopenshell
+import ifcopenshell.geom
+import ifcopenshell.ifcopenshell_wrapper as W
+import ifcopenshell.util.shape
+import sverchok.core.sockets
+from sverchok.node_tree import SverchCustomTreeNode
+
+import ifcsverchok.helper as helper
+
+
+class SvSbShapeOutput(bpy.types.Node, SverchCustomTreeNode, helper.SvIfcCore):
+ """
+ Triggers: Ifc create shape by entity
+ Tooltip: Convert IfcShapeRepresentation to geometry data.
+ """
+
+ bl_idname = "SvSbShapeOutput"
+ bl_label = "IFC Shape Output"
+
+ def sv_init(self, context):
+ helper.create_socket(self.inputs, "Representation", data_type="list[list[ifcopenshell.entity_instance]]")
+ helper.create_socket(self.outputs, "Vers", socket_type=sverchok.core.sockets.SvVerticesSocket)
+ helper.create_socket(self.outputs, "Edgs")
+ helper.create_socket(self.outputs, "Pols")
+
+ def process(self):
+ entity: ifcopenshell.entity_instance = helper.get_socket_value(self.inputs, "Representation")
+ self.create(entity)
+ helper.set_socket_value(self.outputs, "Vers", [self.verts], value_type="FINAL_VALUE")
+ helper.set_socket_value(self.outputs, "Edgs", [self.edges], value_type="FINAL_VALUE")
+ helper.set_socket_value(self.outputs, "Pols", [self.polys], value_type="FINAL_VALUE")
+
+ def create(self, entity: ifcopenshell.entity_instance) -> None:
+ assert bpy.context.scene
+ settings = ifcopenshell.geom.settings()
+ shape = ifcopenshell.geom.create_shape(settings, entity)
+ assert isinstance(shape, W.Triangulation)
+ self.verts = ifcopenshell.util.shape.get_vertices(shape).tolist()
+ self.edges = ifcopenshell.util.shape.get_edges(shape).tolist()
+ self.polys = ifcopenshell.util.shape.get_faces(shape).tolist()
+
+
+def register():
+ bpy.utils.register_class(SvSbShapeOutput)
+
+
+def unregister():
+ bpy.utils.unregister_class(SvSbShapeOutput)
diff --git a/src/ifcsverchok/nodes/ifc/shape_builder/test.py b/src/ifcsverchok/nodes/ifc/shape_builder/test.py
new file mode 100644
index 0000000000..e2fc702721
--- /dev/null
+++ b/src/ifcsverchok/nodes/ifc/shape_builder/test.py
@@ -0,0 +1,55 @@
+# IfcSverchok - IFC Sverchok extension
+# Copyright (C) 2022 Martina Jakubowska
+#
+# This file is part of IfcSverchok.
+#
+# IfcSverchok is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# IfcSverchok is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with IfcSverchok. If not, see .
+
+import bpy
+from sverchok.node_tree import SverchCustomTreeNode
+
+import ifcsverchok.helper
+import ifcsverchok.helper as helper
+
+
+class SvIfcSbTest(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
+ bl_idname = "SvIfcSbTest"
+ bl_label = "IFC Test"
+
+ def sv_init(self, context):
+ helper.create_socket(
+ self.inputs,
+ "Input",
+ )
+ helper.create_socket(
+ self.outputs,
+ "Output",
+ description="Extruded Profile",
+ )
+
+ def process(self):
+ print("test!")
+ self.sv_input_names = ["Input"]
+ super().process()
+
+ def process_ifc(self, input_value: float) -> None:
+ self.outputs["Output"].sv_set([[input_value]])
+
+
+def register():
+ bpy.utils.register_class(SvIfcSbTest)
+
+
+def unregister():
+ bpy.utils.unregister_class(SvIfcSbTest)
diff --git a/src/ifcsverchok/nodes/ifc/sverchok_to_ifc.py b/src/ifcsverchok/nodes/ifc/sverchok_to_ifc.py
index 69ac5f37f3..be06fac1ce 100644
--- a/src/ifcsverchok/nodes/ifc/sverchok_to_ifc.py
+++ b/src/ifcsverchok/nodes/ifc/sverchok_to_ifc.py
@@ -17,12 +17,10 @@
# along with IfcSverchok. If not, see .
import bpy
-import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.api.context
import ifcopenshell.api.geometry
import ifcopenshell.util.representation
-from bpy.props import EnumProperty, FloatVectorProperty, IntProperty, StringProperty
+from bpy.props import EnumProperty, StringProperty
from sverchok.data_structure import ensure_min_nesting, updateNode
from sverchok.node_tree import SverchCustomTreeNode
diff --git a/src/ifcsverchok/nodes/ifc/write_file.py b/src/ifcsverchok/nodes/ifc/write_file.py
index 3a25cd99cc..8d52b3d77a 100644
--- a/src/ifcsverchok/nodes/ifc/write_file.py
+++ b/src/ifcsverchok/nodes/ifc/write_file.py
@@ -20,7 +20,6 @@ from os.path import abspath, splitext
import bpy
import ifcopenshell
-import ifcopenshell.api
import ifcopenshell.api.aggregate
import ifcopenshell.api.root
import ifcopenshell.api.spatial
diff --git a/src/ifcsverchok/pyproject.toml b/src/ifcsverchok/pyproject.toml
new file mode 100644
index 0000000000..6952f66f06
--- /dev/null
+++ b/src/ifcsverchok/pyproject.toml
@@ -0,0 +1,5 @@
+[tool.ruff]
+extend = "../../pyproject.toml"
+lint.select = [
+ "F401", # unused imports
+]