diff --git a/src/bonsai/bonsai/bim/module/aggregate/operator.py b/src/bonsai/bonsai/bim/module/aggregate/operator.py index 9c7b23fcc7..e286afac89 100644 --- a/src/bonsai/bonsai/bim/module/aggregate/operator.py +++ b/src/bonsai/bonsai/bim/module/aggregate/operator.py @@ -19,6 +19,7 @@ import bpy import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.group import ifcopenshell.api.pset import ifcopenshell.util.element import bonsai.tool as tool @@ -301,6 +302,7 @@ class BIM_OT_break_link_to_other_aggregates(bpy.types.Operator, tool.Ifc.Operato bl_options = {"REGISTER", "UNDO"} def _execute(self, context): + ifc_file = tool.Ifc.get() element = tool.Ifc.get_entity(bpy.context.active_object) aggregate = ifcopenshell.util.element.get_aggregate(element) if not aggregate: @@ -312,8 +314,8 @@ class BIM_OT_break_link_to_other_aggregates(bpy.types.Operator, tool.Ifc.Operato for part in parts: pset = ifcopenshell.util.element.get_pset(part, "BBIM_Linked_Aggregate") - pset = tool.Ifc.get().by_id(pset["id"]) - ifcopenshell.api.pset.remove_pset(tool.Ifc.get(), product=part, pset=pset) + pset = ifc_file.by_id(pset["id"]) + ifcopenshell.api.pset.remove_pset(ifc_file, product=part, pset=pset) linked_aggregate_group = next( r.RelatingGroup @@ -321,7 +323,7 @@ class BIM_OT_break_link_to_other_aggregates(bpy.types.Operator, tool.Ifc.Operato if r.is_a("IfcRelAssignsToGroup") if "BBIM_Linked_Aggregate" in r.RelatingGroup.Name ) - tool.Ifc.run("group.unassign_group", group=linked_aggregate_group, products=[aggregate]) + ifcopenshell.api.group.unassign_group(ifc_file, group=linked_aggregate_group, products=[aggregate]) return {"FINISHED"} diff --git a/src/bonsai/bonsai/bim/module/boundary/operator.py b/src/bonsai/bonsai/bim/module/boundary/operator.py index 91fed71e92..be93e5e41d 100644 --- a/src/bonsai/bonsai/bim/module/boundary/operator.py +++ b/src/bonsai/bonsai/bim/module/boundary/operator.py @@ -984,7 +984,7 @@ class AddBoundary(bpy.types.Operator, tool.Ifc.Operator): continue connection_geometry = self.create_connection_geometry_from_polygon(opening_polygon, target_face_matrix) - boundary = tool.Ifc.run("root.create_entity", ifc_class=props.boundary_class) + boundary = ifcopenshell.api.root.create_entity(ifc_file, ifc_class=props.boundary_class) boundary.RelatingSpace = space boundary.RelatedBuildingElement = filling boundary.ConnectionGeometry = connection_geometry diff --git a/src/bonsai/bonsai/bim/module/debug/operator.py b/src/bonsai/bonsai/bim/module/debug/operator.py index 3388d7e469..e9fe6cf811 100644 --- a/src/bonsai/bonsai/bim/module/debug/operator.py +++ b/src/bonsai/bonsai/bim/module/debug/operator.py @@ -26,10 +26,10 @@ import subprocess import platform import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.pset import ifcopenshell.geom import ifcopenshell.util.element import ifcopenshell.util.placement -import ifcopenshell.util.representation import ifcopenshell.util.unit import bonsai.tool as tool import bonsai.core.debug as core @@ -893,6 +893,7 @@ class DebugActiveDrawing(bpy.types.Operator): ) def execute(self, context: bpy.types.Context): + ifc_file = tool.Ifc.get() props = tool.Drawing.get_document_props() drawing_item = props.drawings[props.active_drawing_index] drawing = tool.Ifc.get().by_id(drawing_item.ifc_definition_id) @@ -923,7 +924,7 @@ class DebugActiveDrawing(bpy.types.Operator): excluded_guids = ", ".join([e.GlobalId for e in current_elements if hasattr(e, "GlobalId")]) new_exclude = "" if not original_exclude else f"{original_exclude}, " new_exclude += excluded_guids - tool.Ifc.run("pset.edit_pset", pset=pset, properties={"Exclude": new_exclude}) + ifcopenshell.api.pset.edit_pset(ifc_file, pset=pset, properties={"Exclude": new_exclude}) try: bpy.ops.bim.create_drawing(sync=False) @@ -932,7 +933,7 @@ class DebugActiveDrawing(bpy.types.Operator): # print(e) result = True - tool.Ifc.run("pset.edit_pset", pset=pset, properties={"Exclude": original_exclude}) + ifcopenshell.api.pset.edit_pset(ifc_file, pset=pset, properties={"Exclude": original_exclude}) return result def test_elements(elements: list[ifcopenshell.entity_instance], attempts: int = ATTEMPS) -> None: diff --git a/src/bonsai/bonsai/bim/module/drawing/workspace.py b/src/bonsai/bonsai/bim/module/drawing/workspace.py index 778898b2c0..e6970df7e4 100644 --- a/src/bonsai/bonsai/bim/module/drawing/workspace.py +++ b/src/bonsai/bonsai/bim/module/drawing/workspace.py @@ -19,6 +19,7 @@ import os import bpy +import ifcopenshell.api.group import ifcopenshell.util.element import bonsai.core.geometry import bonsai.core.type @@ -144,13 +145,16 @@ add_layout_hotkey_operator = partial( # TODO: move to operator def create_annotation_occurrence(context): props = tool.Drawing.get_annotation_props() - relating_type = tool.Ifc.get().by_id(int(props.relating_type_id)) + ifc_file = tool.Ifc.get() + relating_type = ifc_file.by_id(int(props.relating_type_id)) object_type = props.object_type drawing = tool.Ifc.get_entity(context.scene.camera) + assert drawing obj = tool.Drawing.create_annotation_object(drawing, object_type) obj.name = relating_type.Name ifc_context = tool.Drawing.get_annotation_context(tool.Drawing.get_drawing_target_view(drawing), object_type) + assert ifc_context relating_type_rep = tool.Drawing.get_annotation_representation(relating_type) element = tool.Drawing.run_root_assign_class( obj=obj, @@ -160,10 +164,11 @@ def create_annotation_occurrence(context): context=ifc_context, ifc_representation_class=tool.Drawing.get_ifc_representation_class(object_type), ) + assert element bonsai.core.type.assign_type(tool.Ifc, tool.Type, element=element, type=relating_type) - tool.Ifc.run("group.assign_group", group=tool.Drawing.get_drawing_group(drawing), products=[element]) + ifcopenshell.api.group.assign_group(ifc_file, group=tool.Drawing.get_drawing_group(drawing), products=[element]) tool.Collector.assign(obj) if relating_type_rep is None and props.object_type == "IMAGE": diff --git a/src/bonsai/bonsai/bim/module/geometry/operator.py b/src/bonsai/bonsai/bim/module/geometry/operator.py index 9875b0e5fa..f59467def6 100644 --- a/src/bonsai/bonsai/bim/module/geometry/operator.py +++ b/src/bonsai/bonsai/bim/module/geometry/operator.py @@ -1165,6 +1165,7 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator): @staticmethod def execute_ifc_duplicate_linked_aggregate_operator(self, context, location_from_3d_cursor=False): + ifc_file = tool.Ifc.get() self.new_active_obj = None self.group_name = "BBIM_Linked_Aggregate" self.pset_name = "BBIM_Linked_Aggregate" @@ -1193,10 +1194,10 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator): pset = ifcopenshell.util.element.get_pset(part, self.pset_name) if not pset: - pset = ifcopenshell.api.pset.add_pset(tool.Ifc.get(), product=part, name=self.pset_name) + pset = ifcopenshell.api.pset.add_pset(ifc_file, product=part, name=self.pset_name) ifcopenshell.api.pset.edit_pset( - tool.Ifc.get(), + ifc_file, pset=pset, properties={"Index": index}, ) @@ -1217,8 +1218,8 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator): if self.group_name in product_groups_name: return - linked_aggregate_group = ifcopenshell.api.group.add_group(tool.Ifc.get(), name=self.group_name) - ifcopenshell.api.group.assign_group(tool.Ifc.get(), products=[element], group=linked_aggregate_group) + linked_aggregate_group = ifcopenshell.api.group.add_group(ifc_file, name=self.group_name) + ifcopenshell.api.group.assign_group(ifc_file, products=[element], group=linked_aggregate_group) def custom_incremental_naming_for_element_assembly(old_to_new): for new in old_to_new.values(): @@ -1256,10 +1257,10 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator): for old, new in old_to_new.items(): pset = ifcopenshell.util.element.get_pset(old, "BBIM_Linked_Aggregate") if pset: - new_pset = ifcopenshell.api.pset.add_pset(tool.Ifc.get(), product=new[0], name=self.pset_name) + new_pset = ifcopenshell.api.pset.add_pset(ifc_file, product=new[0], name=self.pset_name) ifcopenshell.api.pset.edit_pset( - tool.Ifc.get(), + ifc_file, pset=new_pset, properties={"Index": pset["Index"]}, ) @@ -1271,7 +1272,7 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator): if r.is_a("IfcRelAssignsToGroup") if "BBIM_Linked_Aggregate" in r.RelatingGroup.Name ] - tool.Ifc.run("group.assign_group", group=linked_aggregate_group[0], products=new) + ifcopenshell.api.group.assign_group(ifc_file, group=linked_aggregate_group[0], products=new) def get_location_from_3d_cursor(old_to_new, aggregate): base_obj = tool.Ifc.get_object(aggregate) @@ -1287,6 +1288,7 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator): selected_obj = context.selected_objects[0] selected_element = tool.Ifc.get_entity(selected_obj) + assert selected_element if selected_element.is_a("IfcElementAssembly"): pass @@ -2720,6 +2722,7 @@ class EditRepresentationItemShapeAspect(bpy.types.Operator, tool.Ifc.Operator): obj = tool.Geometry.get_active_or_representation_obj() assert obj element = tool.Ifc.get_entity(obj) + assert element props = tool.Geometry.get_object_geometry_props(obj) props.is_editing_item_shape_aspect = False ifc_file = tool.Ifc.get() @@ -2755,11 +2758,12 @@ class EditRepresentationItemShapeAspect(bpy.types.Operator, tool.Ifc.Operator): shape_aspect_representation = tool.Geometry.get_shape_aspect_representation_for_item( shape_aspect, representation_item ) + assert shape_aspect_representation styles = tool.Geometry.get_shape_aspect_styles(element, shape_aspect, representation_item) # TODO this looks wrong to me. In theory styles can be > 1 (e.g. curve # styles) and then the usecase will assign the wrong style. - tool.Ifc.run( - "style.assign_representation_styles", + ifcopenshell.api.style.assign_representation_styles( + ifc_file, shape_representation=shape_aspect_representation, styles=styles, ) diff --git a/src/bonsai/bonsai/bim/module/model/mep.py b/src/bonsai/bonsai/bim/module/model/mep.py index 6c1e90750d..ab96e60b0d 100644 --- a/src/bonsai/bonsai/bim/module/model/mep.py +++ b/src/bonsai/bonsai/bim/module/model/mep.py @@ -28,6 +28,7 @@ import ifcopenshell.api import ifcopenshell.api.geometry import ifcopenshell.api.material import ifcopenshell.api.pset +import ifcopenshell.api.system import ifcopenshell.util.element import ifcopenshell.util.placement import ifcopenshell.util.representation @@ -570,7 +571,9 @@ class MEPGenerator: if length >= segment_data["extrusion_depth"]: return None, "Failed to add obstruction - obstruction length is larger than the segment." + ifc_file = tool.Ifc.get() segment_obj = tool.Ifc.get_object(segment) + assert isinstance(segment_obj, bpy.types.Object) segment_matrix = segment_obj.matrix_world segment_rotation = segment_matrix.to_quaternion() fitting_data = self.get_compatible_fitting_type(segment, related_port, "OBSTRUCTION") @@ -583,6 +586,7 @@ class MEPGenerator: # NOTE: at this point we loose current blender objects selection bpy.ops.bim.add_occurrence(relating_type_id=obstruction_type.id()) obstruction_obj = bpy.context.active_object + assert obstruction_obj obstruction_obj.matrix_world = segment_matrix profile_joiner.set_depth(obstruction_obj, length) @@ -603,7 +607,9 @@ class MEPGenerator: else: obstruction_obj.location += segment_rotation @ V(0, 0, new_segment_length) - tool.Ifc.run("system.connect_port", port1=related_port, port2=obstruction_port, direction="NOTDEFINED") + ifcopenshell.api.system.connect_port( + ifc_file, port1=related_port, port2=obstruction_port, direction="NOTDEFINED" + ) obstruction = tool.Ifc.get_entity(obstruction_obj) return obstruction, None @@ -861,6 +867,7 @@ class MEPAddTransition(bpy.types.Operator, tool.Ifc.Operator): # create transition element bpy.ops.bim.add_occurrence(relating_type_id=transition_type.id()) transition_obj = bpy.context.active_object + assert transition_obj # adjust transition segment rotation and location # required since we'll base our `transition_obj_dir` on this @@ -882,8 +889,8 @@ class MEPAddTransition(bpy.types.Operator, tool.Ifc.Operator): ports = tool.System.get_ports(tool.Ifc.get_entity(transition_obj)) if not start_port_match: start_port, end_port = end_port, start_port - tool.Ifc.run("system.connect_port", port1=ports[0], port2=start_port, direction="NOTDEFINED") - tool.Ifc.run("system.connect_port", port1=ports[1], port2=end_port, direction="NOTDEFINED") + ifcopenshell.api.system.connect_port(ifc_file, port1=ports[0], port2=start_port, direction="NOTDEFINED") + ifcopenshell.api.system.connect_port(ifc_file, port1=ports[1], port2=end_port, direction="NOTDEFINED") return {"FINISHED"} @@ -1256,8 +1263,8 @@ class MEPAddBend(bpy.types.Operator, tool.Ifc.Operator): # We cannot use start_port_match because tool.System.get_ports is unordered if not np.allclose(start_co, port0_co): start_port, end_port = end_port, start_port - tool.Ifc.run("system.connect_port", port1=ports[0], port2=start_port, direction="NOTDEFINED") - tool.Ifc.run("system.connect_port", port1=ports[1], port2=end_port, direction="NOTDEFINED") + ifcopenshell.api.system.connect_port(ifc_file, port1=ports[0], port2=start_port, direction="NOTDEFINED") + ifcopenshell.api.system.connect_port(ifc_file, port1=ports[1], port2=end_port, direction="NOTDEFINED") self.report({"INFO"}, f"Success!.. kind of. The angle was {round(bend_data['angle'])}") return {"FINISHED"} diff --git a/src/bonsai/bonsai/bim/module/model/product.py b/src/bonsai/bonsai/bim/module/model/product.py index 0ccc4906b6..31efc65e9f 100644 --- a/src/bonsai/bonsai/bim/module/model/product.py +++ b/src/bonsai/bonsai/bim/module/model/product.py @@ -25,6 +25,7 @@ import numpy as np import ifcopenshell import ifcopenshell.api import ifcopenshell.api.geometry +import ifcopenshell.api.system import ifcopenshell.util.system import ifcopenshell.util.element import ifcopenshell.util.placement @@ -311,6 +312,7 @@ class AddOccurrence(bpy.types.Operator, tool.Ifc.Operator): row.prop(self, "representation_template", text="") def _execute(self, context): + ifc_file = tool.Ifc.get() props = tool.Model.get_model_props() relating_type_id = self.relating_type_id or props.relating_type_id @@ -503,10 +505,10 @@ class AddOccurrence(bpy.types.Operator, tool.Ifc.Operator): mat = Matrix(ifcopenshell.util.placement.get_local_placement(port.ObjectPlacement)) mat.translation *= unit_scale mat = obj.matrix_world @ mat - new_port = tool.Ifc.run("system.add_port", element=element) + new_port = ifcopenshell.api.system.add_port(ifc_file, element=element) new_port.PredefinedType = port.PredefinedType new_port.SystemType = port.SystemType - tool.Ifc.run("geometry.edit_object_placement", product=new_port, matrix=mat, is_si=True) + ifcopenshell.api.geometry.edit_object_placement(ifc_file, product=new_port, matrix=mat, is_si=True) if ifc_class == "IfcDoorType" and len(context.selected_objects) >= 1: pass diff --git a/src/bonsai/bonsai/bim/module/resource/operator.py b/src/bonsai/bonsai/bim/module/resource/operator.py index 7a72ac0f32..9e6afaa393 100644 --- a/src/bonsai/bonsai/bim/module/resource/operator.py +++ b/src/bonsai/bonsai/bim/module/resource/operator.py @@ -17,6 +17,7 @@ # along with Bonsai. If not, see . import bpy +import ifcopenshell.api.pset from bpy_extras.io_utils import ImportHelper, ExportHelper from bonsai.bim.module.resource.ui import draw_productivity_ui import bonsai.core.resource as core @@ -376,7 +377,8 @@ class AddProductivityData(bpy.types.Operator, tool.Ifc.Operator): bl_options = {"REGISTER", "UNDO"} def _execute(self, context): - tool.Ifc.run("pset.add_pset", product=tool.Resource.get_highlighted_resource(), name="EPset_Productivity") + assert (resource := tool.Resource.get_highlighted_resource()) + ifcopenshell.api.pset.add_pset(tool.Ifc.get(), product=resource, name="EPset_Productivity") class EditProductivityData(bpy.types.Operator, tool.Ifc.Operator): diff --git a/src/bonsai/bonsai/bim/module/resource/prop.py b/src/bonsai/bonsai/bim/module/resource/prop.py index bb7d0a2bf7..710a3ff31d 100644 --- a/src/bonsai/bonsai/bim/module/resource/prop.py +++ b/src/bonsai/bonsai/bim/module/resource/prop.py @@ -18,6 +18,7 @@ import bpy import ifcopenshell.api +import ifcopenshell.api.resource import ifcopenshell.util.resource import bonsai.tool as tool import bonsai.bim.module.pset.data @@ -52,9 +53,10 @@ def updateResourceName(self, context): props = context.scene.BIMResourceProperties if not props.is_resource_update_enabled: return - tool.Ifc.run( - "resource.edit_resource", - resource=tool.Ifc.get().by_id(self.ifc_definition_id), + ifc_file = tool.Ifc.get() + ifcopenshell.api.resource.edit_resource( + ifc_file, + resource=ifc_file.by_id(self.ifc_definition_id), attributes={"Name": self.name}, ) if props.active_resource_id == self.ifc_definition_id: diff --git a/src/bonsai/bonsai/bim/module/spatial/prop.py b/src/bonsai/bonsai/bim/module/spatial/prop.py index 4041821366..1761a03f05 100644 --- a/src/bonsai/bonsai/bim/module/spatial/prop.py +++ b/src/bonsai/bonsai/bim/module/spatial/prop.py @@ -34,7 +34,7 @@ import bonsai.tool as tool import bonsai.bim.handler import bonsai.core.geometry import ifcopenshell -import ifcopenshell.util.element +import ifcopenshell.api.attribute import ifcopenshell.util.unit from typing import TYPE_CHECKING, Union, Literal @@ -74,8 +74,9 @@ def update_name(self: "BIMContainer", context: bpy.types.Context) -> None: def update_long_name(self: "BIMContainer", context: bpy.types.Context) -> None: if ifc_definition_id := self.ifc_definition_id: - element = tool.Ifc.get().by_id(ifc_definition_id) - tool.Ifc.run("attribute.edit_attributes", product=element, attributes={"LongName": self.long_name}) + ifc_file = tool.Ifc.get() + element = ifc_file.by_id(ifc_definition_id) + ifcopenshell.api.attribute.edit_attributes(ifc_file, product=element, attributes={"LongName": self.long_name}) bonsai.bim.handler.refresh_ui_data() diff --git a/src/bonsai/bonsai/bim/module/style/operator.py b/src/bonsai/bonsai/bim/module/style/operator.py index a5a4a16e9b..1916d487ce 100644 --- a/src/bonsai/bonsai/bim/module/style/operator.py +++ b/src/bonsai/bonsai/bim/module/style/operator.py @@ -833,9 +833,9 @@ class EditSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator): assert self.texture_style ifcopenshell.api.style.remove_surface_style(ifc_file, self.texture_style) return - textures = tool.Ifc.run("style.add_surface_textures", textures=textures, uv_maps=[]) - texture_style = tool.Ifc.run( - "style.add_surface_style", + textures = ifcopenshell.api.style.add_surface_textures(ifc_file, textures=textures, uv_maps=[]) + texture_style = ifcopenshell.api.style.add_surface_style( + ifc_file, style=self.style, ifc_class="IfcSurfaceStyleWithTextures", attributes={"Textures": textures}, @@ -864,9 +864,10 @@ class EditSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator): def add_new_style(self) -> None: material = tool.Ifc.get_object(self.style) + ifc_file = tool.Ifc.get() if self.props.is_editing_class == "IfcSurfaceStyleShading": surface_style = ifcopenshell.api.style.add_surface_style( - tool.Ifc.get(), + ifc_file, style=self.style, ifc_class="IfcSurfaceStyleShading", attributes=self.get_shading_attributes(), @@ -874,7 +875,7 @@ class EditSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator): tool.Loader.create_surface_style_shading(material, surface_style) elif self.props.is_editing_class == "IfcSurfaceStyleRendering": surface_style = ifcopenshell.api.style.add_surface_style( - tool.Ifc.get(), + ifc_file, style=self.style, ifc_class="IfcSurfaceStyleRendering", attributes=self.get_rendering_attributes(), @@ -886,9 +887,9 @@ class EditSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator): textures = self.get_texture_attributes() if not textures: return - textures = tool.Ifc.run("style.add_surface_textures", textures=textures, uv_maps=[]) - texture_style = tool.Ifc.run( - "style.add_surface_style", + textures = ifcopenshell.api.style.add_surface_textures(ifc_file, textures=textures, uv_maps=[]) + texture_style = ifcopenshell.api.style.add_surface_style( + ifc_file, style=self.style, ifc_class="IfcSurfaceStyleWithTextures", attributes={"Textures": textures}, diff --git a/src/bonsai/bonsai/bim/module/system/operator.py b/src/bonsai/bonsai/bim/module/system/operator.py index 517b4b48dd..6873131af1 100644 --- a/src/bonsai/bonsai/bim/module/system/operator.py +++ b/src/bonsai/bonsai/bim/module/system/operator.py @@ -512,12 +512,12 @@ class AssignUnassignFlowControl(bpy.types.Operator, tool.Ifc.Operator): for control in flow_controls: if self.assign: - tool.Ifc.run( - "system.assign_flow_control", relating_flow_element=flow_element, related_flow_control=control + ifcopenshell.api.system.assign_flow_control( + ifc_file, relating_flow_element=flow_element, related_flow_control=control ) else: - tool.Ifc.run( - "system.unassign_flow_control", relating_flow_element=flow_element, related_flow_control=control + ifcopenshell.api.system.unassign_flow_control( + ifc_file, relating_flow_element=flow_element, related_flow_control=control ) if from_selected_objects: diff --git a/src/bonsai/bonsai/tool/drawing.py b/src/bonsai/bonsai/tool/drawing.py index 04f5e8c06e..7107bbf4d8 100644 --- a/src/bonsai/bonsai/tool/drawing.py +++ b/src/bonsai/bonsai/tool/drawing.py @@ -39,6 +39,7 @@ import bonsai.core.type import bonsai.tool as tool import ifcopenshell.api import ifcopenshell.api.context +import ifcopenshell.api.drawing import ifcopenshell.api.document import ifcopenshell.api.pset import ifcopenshell.api.root @@ -210,6 +211,7 @@ class Drawing(bonsai.core.tool.Drawing): if not related_object or not (related_entity := tool.Ifc.get_entity(related_object)): return + ifc_file = tool.Ifc.get() obj_entity = tool.Ifc.get_entity(obj) assert obj_entity assign_product = False @@ -267,7 +269,9 @@ class Drawing(bonsai.core.tool.Drawing): assign_product = True if assign_product and not cls.get_assigned_product(obj_entity): - tool.Ifc.run("drawing.assign_product", relating_product=related_entity, related_object=obj_entity) + ifcopenshell.api.drawing.assign_product( + ifc_file, relating_product=related_entity, related_object=obj_entity + ) if object_type == "TEXT": tool.Drawing.update_text_value(obj) @@ -745,8 +749,8 @@ class Drawing(bonsai.core.tool.Drawing): literal = cls.add_literal_to_annotation(obj, **attributes) else: literal = ifc_file.by_id(ifc_definition_id) - tool.Ifc.run( - "drawing.edit_text_literal", + ifcopenshell.api.drawing.edit_text_literal( + ifc_file, text_literal=literal, attributes=attributes, ) diff --git a/src/bonsai/bonsai/tool/geometry.py b/src/bonsai/bonsai/tool/geometry.py index 50cc8ed80b..48a3327e6b 100644 --- a/src/bonsai/bonsai/tool/geometry.py +++ b/src/bonsai/bonsai/tool/geometry.py @@ -30,6 +30,7 @@ import ifcopenshell.api import ifcopenshell.api.boundary import ifcopenshell.api.geometry import ifcopenshell.api.grid +import ifcopenshell.api.group import ifcopenshell.api.profile import ifcopenshell.api.pset import ifcopenshell.api.root @@ -1482,7 +1483,7 @@ class Geometry(bonsai.core.tool.Geometry): # remove shape aspect first otherwise remove_representation won't remove it because of the inverse if len(shape_aspect.ShapeRepresentations) == 1: ifc_file.remove(shape_aspect) - tool.Ifc.run("geometry.remove_representation", representation=representation) + ifcopenshell.api.geometry.remove_representation(ifc_file, representation=representation) else: items = set(representation.Items) - set(representation_items) representation.Items = tuple(items) @@ -2249,6 +2250,7 @@ class Geometry(bonsai.core.tool.Geometry): @classmethod def remove_linked_aggregate_data(cls, old_to_new): + ifc_file = tool.Ifc.get() for old, new in old_to_new.items(): pset = ifcopenshell.util.element.get_pset(new[0], "BBIM_Linked_Aggregate") if pset: @@ -2263,7 +2265,7 @@ class Geometry(bonsai.core.tool.Geometry): if "BBIM_Linked_Aggregate" in r.RelatingGroup.Name ] if linked_aggregate_group: - tool.Ifc.run("group.unassign_group", group=linked_aggregate_group[0], products=[new[0]]) + ifcopenshell.api.group.unassign_group(ifc_file, group=linked_aggregate_group[0], products=[new[0]]) @classmethod def name_item_object(cls, obj: bpy.types.Object, item: ifcopenshell.entity_instance) -> None: diff --git a/src/bonsai/bonsai/tool/georeference.py b/src/bonsai/bonsai/tool/georeference.py index 7b8ee46d24..2b23345fcd 100644 --- a/src/bonsai/bonsai/tool/georeference.py +++ b/src/bonsai/bonsai/tool/georeference.py @@ -44,8 +44,8 @@ class Georeference(bonsai.core.tool.Georeference): @classmethod def add_georeferencing(cls) -> None: props = cls.get_georeference_props() - tool.Ifc.run( - "georeference.add_georeferencing", + ifcopenshell.api.georeference.add_georeferencing( + tool.Ifc.get(), ifc_class=props.coordinate_operation_class, ) diff --git a/src/bonsai/bonsai/tool/ifc.py b/src/bonsai/bonsai/tool/ifc.py index 8672318ba7..760dd8ba49 100644 --- a/src/bonsai/bonsai/tool/ifc.py +++ b/src/bonsai/bonsai/tool/ifc.py @@ -50,6 +50,11 @@ class Ifc(bonsai.core.tool.Ifc): @classmethod def run(cls, command: str, **kwargs) -> Any: + """ + Should be used for core modules only - when actual api modules are not available, + otherwise those calls can be more error prone than explicit calls, + due to the lost type information. + """ return ifcopenshell.api.run(command, IfcStore.get_file(), **kwargs) @classmethod diff --git a/src/bonsai/bonsai/tool/material.py b/src/bonsai/bonsai/tool/material.py index e6e6b16c23..369c5e7d79 100644 --- a/src/bonsai/bonsai/tool/material.py +++ b/src/bonsai/bonsai/tool/material.py @@ -51,7 +51,7 @@ class Material(bonsai.core.tool.Material): @classmethod def duplicate_material(cls, material: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance: - new = tool.Ifc.run("material.copy_material", material=material) + new = ifcopenshell.api.material.copy_material(tool.Ifc.get(), material=material) # Doesn't have a name. if new.is_a("IfcMaterialList"): @@ -233,18 +233,19 @@ class Material(bonsai.core.tool.Material): def add_material_to_set( cls, material_set: ifcopenshell.entity_instance, material: ifcopenshell.entity_instance ) -> None: + ifc_file = tool.Ifc.get() if material_set.is_a("IfcMaterialConstituentSet"): if not material_set.MaterialConstituents: - tool.Ifc.run( - "material.add_constituent", + ifcopenshell.api.material.add_constituent( + ifc_file, constituent_set=material_set, material=material, ) elif material_set.is_a() == "IfcMaterialLayerSet": if not material_set.MaterialLayers: - unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) - layer = tool.Ifc.run( - "material.add_layer", + unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file) + layer = ifcopenshell.api.material.add_layer( + ifc_file, layer_set=material_set, material=material, ) @@ -252,21 +253,21 @@ class Material(bonsai.core.tool.Material): layer.LayerThickness = thickness / unit_scale elif material_set.is_a("IfcMaterialProfileSet"): if not material_set.MaterialProfiles: - named_profiles = [p for p in tool.Ifc.get().by_type("IfcProfileDef") if p.ProfileName] + named_profiles = [p for p in ifc_file.by_type("IfcProfileDef") if p.ProfileName] if named_profiles: profile = named_profiles[0] else: - unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) + unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file) size = 0.5 / unit_scale - profile = tool.Ifc.get().create_entity( + profile = ifc_file.create_entity( "IfcRectangleProfileDef", ProfileName="New Profile", ProfileType="AREA", XDim=size, YDim=size, ) - material_profile = tool.Ifc.run( - "material.add_profile", + material_profile = ifcopenshell.api.material.add_profile( + ifc_file, profile_set=material_set, material=material, profile=profile, @@ -290,6 +291,7 @@ class Material(bonsai.core.tool.Material): def replace_material_with_material_profile( cls, element: ifcopenshell.entity_instance ) -> ifcopenshell.entity_instance: + ifc_file = tool.Ifc.get() old_material = cls.get_material(element, should_inherit=False) old_inherited_material = cls.get_material(element, should_inherit=True) material = old_material if old_material and old_material.is_a("IfcMaterial") else None @@ -299,9 +301,13 @@ class Material(bonsai.core.tool.Material): material = tool.Ifc.get().by_type("IfcMaterial")[0] else: bonsai.core.material.unassign_material(tool.Ifc, tool.Material, objects=[tool.Ifc.get_object(element)]) - tool.Ifc.run("material.assign_material", products=[element], type="IfcMaterialProfileSet", material=material) + ifcopenshell.api.material.assign_material( + ifc_file, products=[element], type="IfcMaterialProfileSet", material=material + ) assinged_material = cls.get_material(element) - material_profile = tool.Ifc.run("material.add_profile", profile_set=assinged_material, material=material) + material_profile = ifcopenshell.api.material.add_profile( + ifc_file, profile_set=assinged_material, material=material + ) return material_profile @classmethod diff --git a/src/bonsai/bonsai/tool/model.py b/src/bonsai/bonsai/tool/model.py index 4b1524db18..b88d9d166a 100644 --- a/src/bonsai/bonsai/tool/model.py +++ b/src/bonsai/bonsai/tool/model.py @@ -1208,7 +1208,7 @@ class Model(bonsai.core.tool.Model): if obj: obj.matrix_world = matrix return - tool.Ifc.run("geometry.edit_object_placement", product=element, matrix=matrix, is_si=True) + ifcopenshell.api.geometry.edit_object_placement(tool.Ifc.get(), product=element, matrix=matrix, is_si=True) @classmethod def sync_object_ifc_position(cls, obj: bpy.types.Object) -> None: diff --git a/src/bonsai/bonsai/tool/resource.py b/src/bonsai/bonsai/tool/resource.py index a8cc8ab396..27fc8ea7ed 100644 --- a/src/bonsai/bonsai/tool/resource.py +++ b/src/bonsai/bonsai/tool/resource.py @@ -27,6 +27,8 @@ import json import time import isodate from datetime import datetime +import ifcopenshell.api.pset +import ifcopenshell.api.resource import ifcopenshell.util.date as ifcdateutils import ifcopenshell.util.cost import ifcopenshell.util.resource @@ -404,9 +406,10 @@ class Resource(bonsai.core.tool.Resource): productivity = cls.get_productivity(resource) if not productivity: return - return tool.Ifc.run( - "pset.edit_pset", - pset=tool.Ifc.get().by_id(productivity["id"]), + ifc_file = tool.Ifc.get() + return ifcopenshell.api.pset.edit_pset( + ifc_file, + pset=ifc_file.by_id(productivity["id"]), properties=attributes, ) @@ -429,12 +432,13 @@ class Resource(bonsai.core.tool.Resource): @classmethod def run_edit_resource_time(cls, resource: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None: + ifc_file = tool.Ifc.get() if not resource.Usage: - tool.Ifc.run( - "resource.add_resource_time", + ifcopenshell.api.resource.add_resource_time( + ifc_file, resource=resource, ) - tool.Ifc.run("resource.edit_resource_time", resource_time=resource.Usage, attributes=attributes) + ifcopenshell.api.resource.edit_resource_time(ifc_file, resource_time=resource.Usage, attributes=attributes) @classmethod def go_to_resource(cls, resource: ifcopenshell.entity_instance) -> None: @@ -459,7 +463,7 @@ class Resource(bonsai.core.tool.Resource): @classmethod def run_calculate_resource_usage(cls, resource: ifcopenshell.entity_instance) -> None: - tool.Ifc.run("resource.calculate_resource_usage", resource=resource) + ifcopenshell.api.resource.calculate_resource_usage(tool.Ifc.get(), resource=resource) @classmethod def calculate_resource_quantity(cls, resource: ifcopenshell.entity_instance) -> None: diff --git a/src/bonsai/bonsai/tool/sequence.py b/src/bonsai/bonsai/tool/sequence.py index ab6e4969be..d0fa5e249a 100644 --- a/src/bonsai/bonsai/tool/sequence.py +++ b/src/bonsai/bonsai/tool/sequence.py @@ -27,6 +27,7 @@ import mathutils import webbrowser import isodate import ifcopenshell +import ifcopenshell.api.group import ifcopenshell.ifcopenshell_wrapper as W import ifcopenshell.util.sequence import ifcopenshell.util.date @@ -1688,12 +1689,13 @@ class Sequence(bonsai.core.tool.Sequence): @classmethod def save_animation_color_scheme(cls, name: str) -> ifcopenshell.entity_instance: props = cls.get_animation_props() + ifc_file = tool.Ifc.get() colour_scheme = { "Inputs": {cs.name: cs.color[0:3] for cs in props.task_input_colors}, "Outputs": {cs.name: cs.color[0:3] for cs in props.task_output_colors}, } - group = [g for g in tool.Ifc.get().by_type("IfcGroup") if g.Name == name] + group = [g for g in ifc_file.by_type("IfcGroup") if g.Name == name] if group: group = group[0] description = json.loads(group.Description) @@ -1701,7 +1703,7 @@ class Sequence(bonsai.core.tool.Sequence): group.Description = json.dumps(description) else: description = json.dumps({"type": "BBIM_AnimationColorScheme", "colourscheme": colour_scheme}) - group = tool.Ifc.run("group.add_group", name=name, description=description) + group = ifcopenshell.api.group.add_group(ifc_file, name=name, description=description) return group[0] @classmethod diff --git a/src/bonsai/bonsai/tool/spatial.py b/src/bonsai/bonsai/tool/spatial.py index 6577f02d6d..e94c15850a 100644 --- a/src/bonsai/bonsai/tool/spatial.py +++ b/src/bonsai/bonsai/tool/spatial.py @@ -22,6 +22,8 @@ import bmesh import shapely import shapely.ops import ifcopenshell +import ifcopenshell.api.attribute +import ifcopenshell.api.type import ifcopenshell.geom import ifcopenshell.util.element import ifcopenshell.util.placement @@ -552,7 +554,7 @@ class Spatial(bonsai.core.tool.Spatial): @classmethod def edit_container_name(cls, container: ifcopenshell.entity_instance, name: str) -> None: - tool.Ifc.run("attribute.edit_attributes", product=container, attributes={"Name": name}) + ifcopenshell.api.attribute.edit_attributes(tool.Ifc.get(), product=container, attributes={"Name": name}) @classmethod def get_active_container(cls) -> Union[ifcopenshell.entity_instance, None]: @@ -1167,13 +1169,15 @@ class Spatial(bonsai.core.tool.Spatial): @classmethod def assign_type_to_obj(cls, obj: bpy.types.Object) -> None: props = tool.Model.get_model_props() + ifc_file = tool.Ifc.get() relating_type_id = props.relating_type_id relating_type = tool.Ifc.get().by_id(int(relating_type_id)) ifc_class = relating_type.is_a() - instance_class = ifcopenshell.util.type.get_applicable_entities(ifc_class, tool.Ifc.get().schema)[0] + instance_class = ifcopenshell.util.type.get_applicable_entities(ifc_class, ifc_file.schema)[0] bpy.ops.bim.assign_class(obj=obj.name, ifc_class=instance_class) element = tool.Ifc.get_entity(obj) - tool.Ifc.run("type.assign_type", related_objects=[element], relating_type=relating_type) + assert element + ifcopenshell.api.type.assign_type(ifc_file, related_objects=[element], relating_type=relating_type) @classmethod def assign_relating_type_to_element( diff --git a/src/bonsai/bonsai/tool/structural.py b/src/bonsai/bonsai/tool/structural.py index b7bf23b481..ce923cf4e4 100644 --- a/src/bonsai/bonsai/tool/structural.py +++ b/src/bonsai/bonsai/tool/structural.py @@ -19,6 +19,7 @@ from __future__ import annotations import bpy import ifcopenshell +import ifcopenshell.api.context import ifcopenshell.util.representation import json import bonsai.bim.helper @@ -67,19 +68,20 @@ class Structural(bonsai.core.tool.Structural): @classmethod def ensure_representation_contexts(cls) -> None: - model = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model") + ifc_file = tool.Ifc.get() + model = ifcopenshell.util.representation.get_context(ifc_file, "Model") if not model: - model = tool.Ifc.run( - "context.add_context", + model = ifcopenshell.api.context.add_context( + ifc_file, context_type="Model", context_identifier="", target_view="", parent=0, ) - graph = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Reference", "GRAPH_VIEW") + graph = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Reference", "GRAPH_VIEW") if not graph: - model = tool.Ifc.run( - "context.add_context", + model = ifcopenshell.api.context.add_context( + ifc_file, context_type="Model", context_identifier="Reference", target_view="GRAPH_VIEW", diff --git a/src/bonsai/bonsai/tool/style.py b/src/bonsai/bonsai/tool/style.py index 0694aec9ca..f8ead02ecb 100644 --- a/src/bonsai/bonsai/tool/style.py +++ b/src/bonsai/bonsai/tool/style.py @@ -614,7 +614,10 @@ class Style(bonsai.core.tool.Style): def assign_style_to_object(cls, style: ifcopenshell.entity_instance, obj: bpy.types.Object) -> None: """assigns `style` to `object` current representation""" representation = tool.Geometry.get_active_representation(obj) - tool.Ifc.run("style.assign_representation_styles", shape_representation=representation, styles=[style]) + assert representation + ifcopenshell.api.style.assign_representation_styles( + tool.Ifc.get(), shape_representation=representation, styles=[style] + ) @classmethod def assign_style_to_representation_item( diff --git a/src/bonsai/bonsai/tool/system.py b/src/bonsai/bonsai/tool/system.py index 649cd22a2b..ce9387a9e9 100644 --- a/src/bonsai/bonsai/tool/system.py +++ b/src/bonsai/bonsai/tool/system.py @@ -18,6 +18,8 @@ from __future__ import annotations import bpy +import ifcopenshell.api.geometry +import ifcopenshell.api.system import ifcopenshell.util.element import ifcopenshell.util.system import bonsai.bim.helper @@ -55,11 +57,13 @@ class System(bonsai.core.tool.System): end_port_pos: Optional[Vector] = None, offset_end_port: Optional[Vector] = None, ) -> list[ifcopenshell.entity_instance]: + ifc_file = tool.Ifc.get() + def add_port(mep_element, matrix): - port = tool.Ifc.run("system.add_port", element=mep_element) + port = ifcopenshell.api.system.add_port(ifc_file, element=mep_element) port.FlowDirection = "NOTDEFINED" port.PredefinedType = tool.System.get_port_predefined_type(mep_element) - tool.Ifc.run("geometry.edit_object_placement", product=port, matrix=matrix, is_si=True) + ifcopenshell.api.geometry.edit_object_placement(ifc_file, product=port, matrix=matrix, is_si=True) return port # make sure obj.dimensions and .matrix_world has valid data diff --git a/src/bonsai/bonsai/tool/web.py b/src/bonsai/bonsai/tool/web.py index a4b1dcd7c7..ec9437d4eb 100644 --- a/src/bonsai/bonsai/tool/web.py +++ b/src/bonsai/bonsai/tool/web.py @@ -25,6 +25,7 @@ from ifcopenshell.util.element import get_psets, get_type, has_property import bonsai.core.tool import bonsai.tool as tool import ifcopenshell.api.sequence +import ifcopenshell.api.classification import ifcopenshell.api.cost from typing import Any, Optional import time @@ -376,28 +377,30 @@ class Web(bonsai.core.tool.Web): tool.Spatial.select_products(products, unhide=True) if operator_data["type"] == "addSummaryCostItem": cost_schedule = ifc_file.by_id(operator_data["costScheduleId"]) - tool.Ifc.run("cost.add_cost_item", cost_schedule=cost_schedule) + ifcopenshell.api.cost.add_cost_item(ifc_file, cost_schedule=cost_schedule) cls.load_cost_schedule_web_ui(cost_schedule) if operator_data["type"] == "addCostItem": if not operator_data["costItemId"]: return cost_item = tool.Ifc.get().by_id(operator_data["costItemId"]) - tool.Ifc.run("cost.add_cost_item", cost_item=cost_item) + ifcopenshell.api.cost.add_cost_item(ifc_file, cost_item=cost_item) cost_schedule = tool.Cost.get_cost_schedule(cost_item=cost_item) cls.load_cost_schedule_web_ui(cost_schedule) if operator_data["type"] == "deleteCostItem": cost_item = tool.Ifc.get().by_id(operator_data["costItemId"]) cost_schedule = tool.Cost.get_cost_schedule(cost_item=cost_item) - tool.Ifc.run("cost.remove_cost_item", cost_item=cost_item) + ifcopenshell.api.cost.remove_cost_item(ifc_file, cost_item=cost_item) cls.load_cost_schedule_web_ui(cost_schedule) if operator_data["type"] == "duplicateCostItem": cost_item = tool.Ifc.get().by_id(operator_data["costItemId"]) cost_schedule = tool.Cost.get_cost_schedule(cost_item=cost_item) - tool.Ifc.run("cost.copy_cost_item", cost_item=cost_item) + ifcopenshell.api.cost.copy_cost_item(ifc_file, cost_item=cost_item) cls.load_cost_schedule_web_ui(cost_schedule) if operator_data["type"] == "editCostItemName": cost_item = tool.Ifc.get().by_id(operator_data["costItemId"]) - tool.Ifc.run("cost.edit_cost_item", cost_item=cost_item, attributes={"Name": operator_data["name"]}) + ifcopenshell.api.cost.edit_cost_item( + ifc_file, cost_item=cost_item, attributes={"Name": operator_data["name"]} + ) if operator_data["type"] == "enableEditingCostValues": cost_item = tool.Ifc.get().by_id(operator_data["costItemId"]) cost_values = ifcopenshell.util.cost.get_cost_values(cost_item) @@ -418,15 +421,15 @@ class Web(bonsai.core.tool.Web): ) if operator_data["type"] == "addSumCostValue": cost_item = ifc_file.by_id(operator_data["costItemId"]) - value = tool.Ifc.run("cost.add_cost_value", parent=cost_item) - tool.Ifc.run("cost.edit_cost_value", cost_value=value, attributes={"Category": "*"}) + value = ifcopenshell.api.cost.add_cost_value(ifc_file, parent=cost_item) + ifcopenshell.api.cost.edit_cost_value(ifc_file, cost_value=value, attributes={"Category": "*"}) cost_schedule = tool.Cost.get_cost_schedule(cost_item=cost_item) cls.load_cost_schedule_web_ui(cost_schedule) if operator_data["type"] == "deleteCostValue": cost_item = ifc_file.by_id(operator_data["costItemId"]) cost_value = ifc_file.by_id(operator_data["costValueId"]) - tool.Ifc.run("cost.remove_cost_value", parent=cost_item, cost_value=cost_value) + ifcopenshell.api.cost.remove_cost_value(ifc_file, parent=cost_item, cost_value=cost_value) cost_schedule = tool.Cost.get_cost_schedule(cost_item=cost_item) cls.load_cost_schedule_web_ui(cost_schedule) if operator_data["type"] == "editCostValues": @@ -473,7 +476,9 @@ class Web(bonsai.core.tool.Web): cost_item_id = operator_data["costItemId"] cost_item = ifc_file.by_id(cost_item_id) cost_schedule = tool.Cost.get_cost_schedule(cost_item) - tool.Ifc.run("cost.add_cost_item_quantity", cost_item=cost_item, ifc_class=operator_data["ifcClass"]) + ifcopenshell.api.cost.add_cost_item_quantity( + ifc_file, cost_item=cost_item, ifc_class=operator_data["ifcClass"] + ) cls.load_cost_schedule_web_ui(cost_schedule) cls.load_cost_item_quantities_ui(cost_item) if operator_data["type"] == "editCostItemQuantity": @@ -481,8 +486,8 @@ class Web(bonsai.core.tool.Web): cost_item = ifc_file.by_id(cost_item_id) cost_schedule = tool.Cost.get_cost_schedule(cost_item) physical_quantity = tool.Ifc.get().by_id(operator_data["quantityId"]) - tool.Ifc.run( - "cost.edit_cost_item_quantity", + ifcopenshell.api.cost.edit_cost_item_quantity( + ifc_file, physical_quantity=physical_quantity, attributes=operator_data["attributes"], ) @@ -491,7 +496,9 @@ class Web(bonsai.core.tool.Web): if operator_data["type"] == "deleteCostItemQuantity": cost_item = ifc_file.by_id(operator_data["costItemId"]) physical_quantity = ifc_file.by_id(operator_data["quantityId"]) - tool.Ifc.run("cost.remove_cost_item_quantity", cost_item=cost_item, physical_quantity=physical_quantity) + ifcopenshell.api.cost.remove_cost_item_quantity( + ifc_file, cost_item=cost_item, physical_quantity=physical_quantity + ) cost_schedule = tool.Cost.get_cost_schedule(cost_item) cls.load_cost_schedule_web_ui(cost_schedule) cls.load_cost_item_quantities_ui(cost_item) @@ -518,7 +525,7 @@ class Web(bonsai.core.tool.Web): cost_item = ifc_file.by_id(operator_data["costItemId"]) cost_schedule = tool.Cost.get_cost_schedule(cost_item) reference = ifc_file.by_id(operator_data["classificationId"]) - tool.Ifc.run("classification.remove_reference", products=[cost_item], reference=reference) + ifcopenshell.api.classification.remove_reference(ifc_file, products=[cost_item], reference=reference) cls.load_cost_schedule_web_ui(cost_schedule) if operator_data["type"] == "addClassificationReference": cost_item = ifc_file.by_id(operator_data["costItemId"]) @@ -530,8 +537,8 @@ class Web(bonsai.core.tool.Web): classification = element break reference = IfcStore.classification_file.by_id(operator_data["classificationId"]) - tool.Ifc.run( - "classification.add_reference", products=[cost_item], reference=reference, classification=classification + ifcopenshell.api.classification.add_reference( + ifc_file, products=[cost_item], reference=reference, classification=classification ) cls.load_cost_schedule_web_ui(cost_schedule) if operator_data["type"] == "assignFromQuery": @@ -562,8 +569,8 @@ class Web(bonsai.core.tool.Web): return products_with_quantity = [r for r in results if has_property(r, prop_name)] if products_with_quantity: - tool.Ifc.run( - "cost.assign_cost_item_quantity", + ifcopenshell.api.cost.assign_cost_item_quantity( + ifc_file, cost_item=cost_item, products=results, prop_name=prop_name, @@ -592,7 +599,7 @@ class Web(bonsai.core.tool.Web): cost_schedule = tool.Cost.get_cost_schedule(ifc_file.by_id(operator_data["costItemIds"][0])) for cost_item_id in operator_data["costItemIds"]: cost_item = ifc_file.by_id(cost_item_id) - tool.Ifc.run("cost.assign_cost_value", cost_item=cost_item, cost_rate=cost_rate) + ifcopenshell.api.cost.assign_cost_value(ifc_file, cost_item=cost_item, cost_rate=cost_rate) cls.load_cost_schedule_web_ui(cost_schedule) @classmethod diff --git a/src/bonsai/test/tool/test_geometry.py b/src/bonsai/test/tool/test_geometry.py index aa9ca65211..93198a2f51 100644 --- a/src/bonsai/test/tool/test_geometry.py +++ b/src/bonsai/test/tool/test_geometry.py @@ -634,7 +634,7 @@ class TestCreateShapeAspect(NewFile): item = ifc.createIfcExtrudedAreaSolid() items = [item] representation = ifc.createIfcShapeRepresentation(Items=items, ContextOfItems=context) - tool.Ifc.run("geometry.assign_representation", product=element, representation=representation) + ifcopenshell.api.geometry.assign_representation(ifc, product=element, representation=representation) product_shape = element.RepresentationMaps[0] if use_element_type else element.Representation subject.create_shape_aspect(product_shape, representation, items, None) @@ -653,7 +653,7 @@ class TestAddRepresentationItemToShapeAspect(NewFile): items = [ifc.createIfcExtrudedAreaSolid(), ifc.createIfcExtrudedAreaSolid()] representation = ifc.createIfcShapeRepresentation(Items=items, ContextOfItems=context) - tool.Ifc.run("geometry.assign_representation", product=element, representation=representation) + ifcopenshell.api.geometry.assign_representation(ifc, product=element, representation=representation) product_shape = element.Representation shape_aspect0 = subject.create_shape_aspect(product_shape, representation, [items[0]], None) previous_shape_aspect_id = shape_aspect0.id() @@ -676,7 +676,7 @@ class TestRemoveRepresentationItemFromShapeAspect(NewFile): items = [ifc.createIfcExtrudedAreaSolid(), ifc.createIfcExtrudedAreaSolid()] representation = ifc.createIfcShapeRepresentation(Items=items, ContextOfItems=context) - tool.Ifc.run("geometry.assign_representation", product=element, representation=representation) + ifcopenshell.api.geometry.assign_representation(ifc, product=element, representation=representation) product_shape = element.Representation shape_aspect0 = subject.create_shape_aspect(product_shape, representation, [items[0]], None) previous_shape_aspect_id = shape_aspect0.id() diff --git a/src/bonsai/test/tool/test_loader.py b/src/bonsai/test/tool/test_loader.py index 1eaadf96ec..9845f50342 100644 --- a/src/bonsai/test/tool/test_loader.py +++ b/src/bonsai/test/tool/test_loader.py @@ -19,6 +19,7 @@ import bpy import bmesh import ifcopenshell +import ifcopenshell.api.style import ifcopenshell.util.schema import bonsai.core.tool import bonsai.tool as tool @@ -97,7 +98,9 @@ class TestCreatingStyles(NewFile): ifc_path = Path("test/files/temp/test.ifc").absolute() bpy.ops.bim.save_project(filepath=str(ifc_path), should_save_as=True) - style = tool.Ifc.run("style.add_style", name="test") + ifc_file = tool.Ifc.get() + + style = ifcopenshell.api.style.add_style(ifc_file, name="test") material = bpy.data.materials.new(style.Name) tool.Ifc.link(style, material) get_color = lambda value: {color: value for color in ("Red", "Green", "Blue")} @@ -109,8 +112,8 @@ class TestCreatingStyles(NewFile): "SpecularHighlight": {"IfcSpecularRoughness": 0.4}, "SpecularColour": 0.03, } - rendering_style = tool.Ifc.run( - "style.add_surface_style", + rendering_style = ifcopenshell.api.style.add_surface_style( + ifc_file, style=style, ifc_class="IfcSurfaceStyleRendering", attributes=rendering_attributes, @@ -125,9 +128,9 @@ class TestCreatingStyles(NewFile): "uv_mode": "Generated", } ] - textures = tool.Ifc.run("style.add_surface_textures", textures=textures, uv_maps=[]) - texture_style = tool.Ifc.run( - "style.add_surface_style", + textures = ifcopenshell.api.style.add_surface_textures(ifc_file, textures=textures, uv_maps=[]) + texture_style = ifcopenshell.api.style.add_surface_style( + ifc_file, style=style, ifc_class="IfcSurfaceStyleWithTextures", attributes={"Textures": textures}, @@ -162,7 +165,7 @@ class TestCreatingStyles(NewFile): bpy.ops.bim.create_project() ifc_file = tool.Ifc.get() - style = tool.Ifc.run("style.add_style", name="test") + style = ifcopenshell.api.style.add_style(ifc_file, name="test") material = bpy.data.materials.new(style.Name) tool.Ifc.link(style, material) get_color = lambda value: {color: value for color in ("Red", "Green", "Blue")} @@ -174,8 +177,8 @@ class TestCreatingStyles(NewFile): "SpecularHighlight": {"IfcSpecularRoughness": 0.4}, "SpecularColour": 0.03, } - rendering_style = tool.Ifc.run( - "style.add_surface_style", + rendering_style = ifcopenshell.api.style.add_surface_style( + ifc_file, style=style, ifc_class="IfcSurfaceStyleRendering", attributes=rendering_attributes, @@ -239,8 +242,8 @@ class TestCreatingStyles(NewFile): # setup UV ifc_file.create_entity("IfcTextureCoordinateGenerator", Maps=textures, Mode="COORD") - texture_style = tool.Ifc.run( - "style.add_surface_style", + texture_style = ifcopenshell.api.style.add_surface_style( + ifc_file, style=style, ifc_class="IfcSurfaceStyleWithTextures", attributes={"Textures": textures}, @@ -332,7 +335,7 @@ class TestCreatingStyles(NewFile): bpy.ops.bim.create_project() ifc_file = tool.Ifc.get() - style = tool.Ifc.run("style.add_style", name="test") + style = ifcopenshell.api.style.add_style(ifc_file, name="test") material = bpy.data.materials.new(style.Name) tool.Ifc.link(style, material) get_color = lambda value: {color: value for color in ("Red", "Green", "Blue")} @@ -344,8 +347,8 @@ class TestCreatingStyles(NewFile): "SpecularHighlight": {"IfcSpecularRoughness": 0.4}, "SpecularColour": 0.03, } - rendering_style = tool.Ifc.run( - "style.add_surface_style", + rendering_style = ifcopenshell.api.style.add_surface_style( + ifc_file, style=style, ifc_class="IfcSurfaceStyleRendering", attributes=rendering_attributes, @@ -374,8 +377,8 @@ class TestCreatingStyles(NewFile): # setup UV ifc_file.create_entity("IfcTextureCoordinateGenerator", Maps=textures, Mode="COORD") - texture_style = tool.Ifc.run( - "style.add_surface_style", + texture_style = ifcopenshell.api.style.add_surface_style( + ifc_file, style=style, ifc_class="IfcSurfaceStyleWithTextures", attributes={"Textures": textures}, diff --git a/src/bonsai/test/tool/test_model.py b/src/bonsai/test/tool/test_model.py index 2176eac7b0..670c0cfc37 100644 --- a/src/bonsai/test/tool/test_model.py +++ b/src/bonsai/test/tool/test_model.py @@ -76,7 +76,7 @@ class TestGetBooleans(NewFile): items = [ifc.createIfcExtrudedAreaSolid()] representation = ifc.createIfcShapeRepresentation(Items=items, ContextOfItems=context) - tool.Ifc.run("geometry.assign_representation", product=element, representation=representation) + ifcopenshell.api.geometry.assign_representation(ifc, product=element, representation=representation) builder = ifcopenshell.util.shape_builder.ShapeBuilder(ifc) cut1 = builder.half_space_solid(builder.plane()) @@ -96,7 +96,7 @@ class TestGetManualBooleans(NewFile): items = [ifc.createIfcExtrudedAreaSolid()] representation = ifc.createIfcShapeRepresentation(Items=items, ContextOfItems=context) - tool.Ifc.run("geometry.assign_representation", product=element, representation=representation) + ifcopenshell.api.geometry.assign_representation(ifc, product=element, representation=representation) builder = ifcopenshell.util.shape_builder.ShapeBuilder(ifc) cut1 = builder.half_space_solid(builder.plane())