tool.ifc.run - replace with direct api calls

This commit is contained in:
Andrej730
2025-06-18 17:26:32 +05:00
parent a72e1231f2
commit b1bfe5c3b3
28 changed files with 198 additions and 125 deletions
@@ -19,6 +19,7 @@
import bpy import bpy
import ifcopenshell import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.api.group
import ifcopenshell.api.pset import ifcopenshell.api.pset
import ifcopenshell.util.element import ifcopenshell.util.element
import bonsai.tool as tool 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"} bl_options = {"REGISTER", "UNDO"}
def _execute(self, context): def _execute(self, context):
ifc_file = tool.Ifc.get()
element = tool.Ifc.get_entity(bpy.context.active_object) element = tool.Ifc.get_entity(bpy.context.active_object)
aggregate = ifcopenshell.util.element.get_aggregate(element) aggregate = ifcopenshell.util.element.get_aggregate(element)
if not aggregate: 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: for part in parts:
pset = ifcopenshell.util.element.get_pset(part, "BBIM_Linked_Aggregate") pset = ifcopenshell.util.element.get_pset(part, "BBIM_Linked_Aggregate")
pset = tool.Ifc.get().by_id(pset["id"]) pset = ifc_file.by_id(pset["id"])
ifcopenshell.api.pset.remove_pset(tool.Ifc.get(), product=part, pset=pset) ifcopenshell.api.pset.remove_pset(ifc_file, product=part, pset=pset)
linked_aggregate_group = next( linked_aggregate_group = next(
r.RelatingGroup 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 r.is_a("IfcRelAssignsToGroup")
if "BBIM_Linked_Aggregate" in r.RelatingGroup.Name 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"} return {"FINISHED"}
@@ -984,7 +984,7 @@ class AddBoundary(bpy.types.Operator, tool.Ifc.Operator):
continue continue
connection_geometry = self.create_connection_geometry_from_polygon(opening_polygon, target_face_matrix) 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.RelatingSpace = space
boundary.RelatedBuildingElement = filling boundary.RelatedBuildingElement = filling
boundary.ConnectionGeometry = connection_geometry boundary.ConnectionGeometry = connection_geometry
@@ -26,10 +26,10 @@ import subprocess
import platform import platform
import ifcopenshell import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.api.pset
import ifcopenshell.geom import ifcopenshell.geom
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.placement import ifcopenshell.util.placement
import ifcopenshell.util.representation
import ifcopenshell.util.unit import ifcopenshell.util.unit
import bonsai.tool as tool import bonsai.tool as tool
import bonsai.core.debug as core import bonsai.core.debug as core
@@ -893,6 +893,7 @@ class DebugActiveDrawing(bpy.types.Operator):
) )
def execute(self, context: bpy.types.Context): def execute(self, context: bpy.types.Context):
ifc_file = tool.Ifc.get()
props = tool.Drawing.get_document_props() props = tool.Drawing.get_document_props()
drawing_item = props.drawings[props.active_drawing_index] drawing_item = props.drawings[props.active_drawing_index]
drawing = tool.Ifc.get().by_id(drawing_item.ifc_definition_id) 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")]) 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 = "" if not original_exclude else f"{original_exclude}, "
new_exclude += excluded_guids 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: try:
bpy.ops.bim.create_drawing(sync=False) bpy.ops.bim.create_drawing(sync=False)
@@ -932,7 +933,7 @@ class DebugActiveDrawing(bpy.types.Operator):
# print(e) # print(e)
result = True 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 return result
def test_elements(elements: list[ifcopenshell.entity_instance], attempts: int = ATTEMPS) -> None: def test_elements(elements: list[ifcopenshell.entity_instance], attempts: int = ATTEMPS) -> None:
@@ -19,6 +19,7 @@
import os import os
import bpy import bpy
import ifcopenshell.api.group
import ifcopenshell.util.element import ifcopenshell.util.element
import bonsai.core.geometry import bonsai.core.geometry
import bonsai.core.type import bonsai.core.type
@@ -144,13 +145,16 @@ add_layout_hotkey_operator = partial(
# TODO: move to operator # TODO: move to operator
def create_annotation_occurrence(context): def create_annotation_occurrence(context):
props = tool.Drawing.get_annotation_props() 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 object_type = props.object_type
drawing = tool.Ifc.get_entity(context.scene.camera) drawing = tool.Ifc.get_entity(context.scene.camera)
assert drawing
obj = tool.Drawing.create_annotation_object(drawing, object_type) obj = tool.Drawing.create_annotation_object(drawing, object_type)
obj.name = relating_type.Name obj.name = relating_type.Name
ifc_context = tool.Drawing.get_annotation_context(tool.Drawing.get_drawing_target_view(drawing), object_type) 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) relating_type_rep = tool.Drawing.get_annotation_representation(relating_type)
element = tool.Drawing.run_root_assign_class( element = tool.Drawing.run_root_assign_class(
obj=obj, obj=obj,
@@ -160,10 +164,11 @@ def create_annotation_occurrence(context):
context=ifc_context, context=ifc_context,
ifc_representation_class=tool.Drawing.get_ifc_representation_class(object_type), 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) 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) tool.Collector.assign(obj)
if relating_type_rep is None and props.object_type == "IMAGE": if relating_type_rep is None and props.object_type == "IMAGE":
@@ -1165,6 +1165,7 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator):
@staticmethod @staticmethod
def execute_ifc_duplicate_linked_aggregate_operator(self, context, location_from_3d_cursor=False): 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.new_active_obj = None
self.group_name = "BBIM_Linked_Aggregate" self.group_name = "BBIM_Linked_Aggregate"
self.pset_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) pset = ifcopenshell.util.element.get_pset(part, self.pset_name)
if not pset: 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( ifcopenshell.api.pset.edit_pset(
tool.Ifc.get(), ifc_file,
pset=pset, pset=pset,
properties={"Index": index}, properties={"Index": index},
) )
@@ -1217,8 +1218,8 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator):
if self.group_name in product_groups_name: if self.group_name in product_groups_name:
return return
linked_aggregate_group = ifcopenshell.api.group.add_group(tool.Ifc.get(), name=self.group_name) linked_aggregate_group = ifcopenshell.api.group.add_group(ifc_file, name=self.group_name)
ifcopenshell.api.group.assign_group(tool.Ifc.get(), products=[element], group=linked_aggregate_group) ifcopenshell.api.group.assign_group(ifc_file, products=[element], group=linked_aggregate_group)
def custom_incremental_naming_for_element_assembly(old_to_new): def custom_incremental_naming_for_element_assembly(old_to_new):
for new in old_to_new.values(): for new in old_to_new.values():
@@ -1256,10 +1257,10 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator):
for old, new in old_to_new.items(): for old, new in old_to_new.items():
pset = ifcopenshell.util.element.get_pset(old, "BBIM_Linked_Aggregate") pset = ifcopenshell.util.element.get_pset(old, "BBIM_Linked_Aggregate")
if pset: 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( ifcopenshell.api.pset.edit_pset(
tool.Ifc.get(), ifc_file,
pset=new_pset, pset=new_pset,
properties={"Index": pset["Index"]}, properties={"Index": pset["Index"]},
) )
@@ -1271,7 +1272,7 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator):
if r.is_a("IfcRelAssignsToGroup") if r.is_a("IfcRelAssignsToGroup")
if "BBIM_Linked_Aggregate" in r.RelatingGroup.Name 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): def get_location_from_3d_cursor(old_to_new, aggregate):
base_obj = tool.Ifc.get_object(aggregate) base_obj = tool.Ifc.get_object(aggregate)
@@ -1287,6 +1288,7 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator):
selected_obj = context.selected_objects[0] selected_obj = context.selected_objects[0]
selected_element = tool.Ifc.get_entity(selected_obj) selected_element = tool.Ifc.get_entity(selected_obj)
assert selected_element
if selected_element.is_a("IfcElementAssembly"): if selected_element.is_a("IfcElementAssembly"):
pass pass
@@ -2720,6 +2722,7 @@ class EditRepresentationItemShapeAspect(bpy.types.Operator, tool.Ifc.Operator):
obj = tool.Geometry.get_active_or_representation_obj() obj = tool.Geometry.get_active_or_representation_obj()
assert obj assert obj
element = tool.Ifc.get_entity(obj) element = tool.Ifc.get_entity(obj)
assert element
props = tool.Geometry.get_object_geometry_props(obj) props = tool.Geometry.get_object_geometry_props(obj)
props.is_editing_item_shape_aspect = False props.is_editing_item_shape_aspect = False
ifc_file = tool.Ifc.get() 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 = tool.Geometry.get_shape_aspect_representation_for_item(
shape_aspect, representation_item shape_aspect, representation_item
) )
assert shape_aspect_representation
styles = tool.Geometry.get_shape_aspect_styles(element, shape_aspect, representation_item) 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 # 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. # styles) and then the usecase will assign the wrong style.
tool.Ifc.run( ifcopenshell.api.style.assign_representation_styles(
"style.assign_representation_styles", ifc_file,
shape_representation=shape_aspect_representation, shape_representation=shape_aspect_representation,
styles=styles, styles=styles,
) )
+12 -5
View File
@@ -28,6 +28,7 @@ import ifcopenshell.api
import ifcopenshell.api.geometry import ifcopenshell.api.geometry
import ifcopenshell.api.material import ifcopenshell.api.material
import ifcopenshell.api.pset import ifcopenshell.api.pset
import ifcopenshell.api.system
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.placement import ifcopenshell.util.placement
import ifcopenshell.util.representation import ifcopenshell.util.representation
@@ -570,7 +571,9 @@ class MEPGenerator:
if length >= segment_data["extrusion_depth"]: if length >= segment_data["extrusion_depth"]:
return None, "Failed to add obstruction - obstruction length is larger than the segment." 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) segment_obj = tool.Ifc.get_object(segment)
assert isinstance(segment_obj, bpy.types.Object)
segment_matrix = segment_obj.matrix_world segment_matrix = segment_obj.matrix_world
segment_rotation = segment_matrix.to_quaternion() segment_rotation = segment_matrix.to_quaternion()
fitting_data = self.get_compatible_fitting_type(segment, related_port, "OBSTRUCTION") 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 # NOTE: at this point we loose current blender objects selection
bpy.ops.bim.add_occurrence(relating_type_id=obstruction_type.id()) bpy.ops.bim.add_occurrence(relating_type_id=obstruction_type.id())
obstruction_obj = bpy.context.active_object obstruction_obj = bpy.context.active_object
assert obstruction_obj
obstruction_obj.matrix_world = segment_matrix obstruction_obj.matrix_world = segment_matrix
profile_joiner.set_depth(obstruction_obj, length) profile_joiner.set_depth(obstruction_obj, length)
@@ -603,7 +607,9 @@ class MEPGenerator:
else: else:
obstruction_obj.location += segment_rotation @ V(0, 0, new_segment_length) 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) obstruction = tool.Ifc.get_entity(obstruction_obj)
return obstruction, None return obstruction, None
@@ -861,6 +867,7 @@ class MEPAddTransition(bpy.types.Operator, tool.Ifc.Operator):
# create transition element # create transition element
bpy.ops.bim.add_occurrence(relating_type_id=transition_type.id()) bpy.ops.bim.add_occurrence(relating_type_id=transition_type.id())
transition_obj = bpy.context.active_object transition_obj = bpy.context.active_object
assert transition_obj
# adjust transition segment rotation and location # adjust transition segment rotation and location
# required since we'll base our `transition_obj_dir` on this # 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)) ports = tool.System.get_ports(tool.Ifc.get_entity(transition_obj))
if not start_port_match: if not start_port_match:
start_port, end_port = end_port, start_port start_port, end_port = end_port, start_port
tool.Ifc.run("system.connect_port", port1=ports[0], port2=start_port, direction="NOTDEFINED") ifcopenshell.api.system.connect_port(ifc_file, 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[1], port2=end_port, direction="NOTDEFINED")
return {"FINISHED"} 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 # We cannot use start_port_match because tool.System.get_ports is unordered
if not np.allclose(start_co, port0_co): if not np.allclose(start_co, port0_co):
start_port, end_port = end_port, start_port start_port, end_port = end_port, start_port
tool.Ifc.run("system.connect_port", port1=ports[0], port2=start_port, direction="NOTDEFINED") ifcopenshell.api.system.connect_port(ifc_file, 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[1], port2=end_port, direction="NOTDEFINED")
self.report({"INFO"}, f"Success!.. kind of. The angle was {round(bend_data['angle'])}") self.report({"INFO"}, f"Success!.. kind of. The angle was {round(bend_data['angle'])}")
return {"FINISHED"} return {"FINISHED"}
@@ -25,6 +25,7 @@ import numpy as np
import ifcopenshell import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.api.geometry import ifcopenshell.api.geometry
import ifcopenshell.api.system
import ifcopenshell.util.system import ifcopenshell.util.system
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.placement import ifcopenshell.util.placement
@@ -311,6 +312,7 @@ class AddOccurrence(bpy.types.Operator, tool.Ifc.Operator):
row.prop(self, "representation_template", text="") row.prop(self, "representation_template", text="")
def _execute(self, context): def _execute(self, context):
ifc_file = tool.Ifc.get()
props = tool.Model.get_model_props() props = tool.Model.get_model_props()
relating_type_id = self.relating_type_id or props.relating_type_id 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 = Matrix(ifcopenshell.util.placement.get_local_placement(port.ObjectPlacement))
mat.translation *= unit_scale mat.translation *= unit_scale
mat = obj.matrix_world @ mat 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.PredefinedType = port.PredefinedType
new_port.SystemType = port.SystemType 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: if ifc_class == "IfcDoorType" and len(context.selected_objects) >= 1:
pass pass
@@ -17,6 +17,7 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy import bpy
import ifcopenshell.api.pset
from bpy_extras.io_utils import ImportHelper, ExportHelper from bpy_extras.io_utils import ImportHelper, ExportHelper
from bonsai.bim.module.resource.ui import draw_productivity_ui from bonsai.bim.module.resource.ui import draw_productivity_ui
import bonsai.core.resource as core import bonsai.core.resource as core
@@ -376,7 +377,8 @@ class AddProductivityData(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def _execute(self, context): 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): class EditProductivityData(bpy.types.Operator, tool.Ifc.Operator):
@@ -18,6 +18,7 @@
import bpy import bpy
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.api.resource
import ifcopenshell.util.resource import ifcopenshell.util.resource
import bonsai.tool as tool import bonsai.tool as tool
import bonsai.bim.module.pset.data import bonsai.bim.module.pset.data
@@ -52,9 +53,10 @@ def updateResourceName(self, context):
props = context.scene.BIMResourceProperties props = context.scene.BIMResourceProperties
if not props.is_resource_update_enabled: if not props.is_resource_update_enabled:
return return
tool.Ifc.run( ifc_file = tool.Ifc.get()
"resource.edit_resource", ifcopenshell.api.resource.edit_resource(
resource=tool.Ifc.get().by_id(self.ifc_definition_id), ifc_file,
resource=ifc_file.by_id(self.ifc_definition_id),
attributes={"Name": self.name}, attributes={"Name": self.name},
) )
if props.active_resource_id == self.ifc_definition_id: if props.active_resource_id == self.ifc_definition_id:
+4 -3
View File
@@ -34,7 +34,7 @@ import bonsai.tool as tool
import bonsai.bim.handler import bonsai.bim.handler
import bonsai.core.geometry import bonsai.core.geometry
import ifcopenshell import ifcopenshell
import ifcopenshell.util.element import ifcopenshell.api.attribute
import ifcopenshell.util.unit import ifcopenshell.util.unit
from typing import TYPE_CHECKING, Union, Literal 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: def update_long_name(self: "BIMContainer", context: bpy.types.Context) -> None:
if ifc_definition_id := self.ifc_definition_id: if ifc_definition_id := self.ifc_definition_id:
element = tool.Ifc.get().by_id(ifc_definition_id) ifc_file = tool.Ifc.get()
tool.Ifc.run("attribute.edit_attributes", product=element, attributes={"LongName": self.long_name}) 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() bonsai.bim.handler.refresh_ui_data()
@@ -833,9 +833,9 @@ class EditSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator):
assert self.texture_style assert self.texture_style
ifcopenshell.api.style.remove_surface_style(ifc_file, self.texture_style) ifcopenshell.api.style.remove_surface_style(ifc_file, self.texture_style)
return return
textures = tool.Ifc.run("style.add_surface_textures", textures=textures, uv_maps=[]) textures = ifcopenshell.api.style.add_surface_textures(ifc_file, textures=textures, uv_maps=[])
texture_style = tool.Ifc.run( texture_style = ifcopenshell.api.style.add_surface_style(
"style.add_surface_style", ifc_file,
style=self.style, style=self.style,
ifc_class="IfcSurfaceStyleWithTextures", ifc_class="IfcSurfaceStyleWithTextures",
attributes={"Textures": textures}, attributes={"Textures": textures},
@@ -864,9 +864,10 @@ class EditSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator):
def add_new_style(self) -> None: def add_new_style(self) -> None:
material = tool.Ifc.get_object(self.style) material = tool.Ifc.get_object(self.style)
ifc_file = tool.Ifc.get()
if self.props.is_editing_class == "IfcSurfaceStyleShading": if self.props.is_editing_class == "IfcSurfaceStyleShading":
surface_style = ifcopenshell.api.style.add_surface_style( surface_style = ifcopenshell.api.style.add_surface_style(
tool.Ifc.get(), ifc_file,
style=self.style, style=self.style,
ifc_class="IfcSurfaceStyleShading", ifc_class="IfcSurfaceStyleShading",
attributes=self.get_shading_attributes(), 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) tool.Loader.create_surface_style_shading(material, surface_style)
elif self.props.is_editing_class == "IfcSurfaceStyleRendering": elif self.props.is_editing_class == "IfcSurfaceStyleRendering":
surface_style = ifcopenshell.api.style.add_surface_style( surface_style = ifcopenshell.api.style.add_surface_style(
tool.Ifc.get(), ifc_file,
style=self.style, style=self.style,
ifc_class="IfcSurfaceStyleRendering", ifc_class="IfcSurfaceStyleRendering",
attributes=self.get_rendering_attributes(), attributes=self.get_rendering_attributes(),
@@ -886,9 +887,9 @@ class EditSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator):
textures = self.get_texture_attributes() textures = self.get_texture_attributes()
if not textures: if not textures:
return return
textures = tool.Ifc.run("style.add_surface_textures", textures=textures, uv_maps=[]) textures = ifcopenshell.api.style.add_surface_textures(ifc_file, textures=textures, uv_maps=[])
texture_style = tool.Ifc.run( texture_style = ifcopenshell.api.style.add_surface_style(
"style.add_surface_style", ifc_file,
style=self.style, style=self.style,
ifc_class="IfcSurfaceStyleWithTextures", ifc_class="IfcSurfaceStyleWithTextures",
attributes={"Textures": textures}, attributes={"Textures": textures},
@@ -512,12 +512,12 @@ class AssignUnassignFlowControl(bpy.types.Operator, tool.Ifc.Operator):
for control in flow_controls: for control in flow_controls:
if self.assign: if self.assign:
tool.Ifc.run( ifcopenshell.api.system.assign_flow_control(
"system.assign_flow_control", relating_flow_element=flow_element, related_flow_control=control ifc_file, relating_flow_element=flow_element, related_flow_control=control
) )
else: else:
tool.Ifc.run( ifcopenshell.api.system.unassign_flow_control(
"system.unassign_flow_control", relating_flow_element=flow_element, related_flow_control=control ifc_file, relating_flow_element=flow_element, related_flow_control=control
) )
if from_selected_objects: if from_selected_objects:
+7 -3
View File
@@ -39,6 +39,7 @@ import bonsai.core.type
import bonsai.tool as tool import bonsai.tool as tool
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.api.context import ifcopenshell.api.context
import ifcopenshell.api.drawing
import ifcopenshell.api.document import ifcopenshell.api.document
import ifcopenshell.api.pset import ifcopenshell.api.pset
import ifcopenshell.api.root 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)): if not related_object or not (related_entity := tool.Ifc.get_entity(related_object)):
return return
ifc_file = tool.Ifc.get()
obj_entity = tool.Ifc.get_entity(obj) obj_entity = tool.Ifc.get_entity(obj)
assert obj_entity assert obj_entity
assign_product = False assign_product = False
@@ -267,7 +269,9 @@ class Drawing(bonsai.core.tool.Drawing):
assign_product = True assign_product = True
if assign_product and not cls.get_assigned_product(obj_entity): 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": if object_type == "TEXT":
tool.Drawing.update_text_value(obj) tool.Drawing.update_text_value(obj)
@@ -745,8 +749,8 @@ class Drawing(bonsai.core.tool.Drawing):
literal = cls.add_literal_to_annotation(obj, **attributes) literal = cls.add_literal_to_annotation(obj, **attributes)
else: else:
literal = ifc_file.by_id(ifc_definition_id) literal = ifc_file.by_id(ifc_definition_id)
tool.Ifc.run( ifcopenshell.api.drawing.edit_text_literal(
"drawing.edit_text_literal", ifc_file,
text_literal=literal, text_literal=literal,
attributes=attributes, attributes=attributes,
) )
+4 -2
View File
@@ -30,6 +30,7 @@ import ifcopenshell.api
import ifcopenshell.api.boundary import ifcopenshell.api.boundary
import ifcopenshell.api.geometry import ifcopenshell.api.geometry
import ifcopenshell.api.grid import ifcopenshell.api.grid
import ifcopenshell.api.group
import ifcopenshell.api.profile import ifcopenshell.api.profile
import ifcopenshell.api.pset import ifcopenshell.api.pset
import ifcopenshell.api.root 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 # remove shape aspect first otherwise remove_representation won't remove it because of the inverse
if len(shape_aspect.ShapeRepresentations) == 1: if len(shape_aspect.ShapeRepresentations) == 1:
ifc_file.remove(shape_aspect) ifc_file.remove(shape_aspect)
tool.Ifc.run("geometry.remove_representation", representation=representation) ifcopenshell.api.geometry.remove_representation(ifc_file, representation=representation)
else: else:
items = set(representation.Items) - set(representation_items) items = set(representation.Items) - set(representation_items)
representation.Items = tuple(items) representation.Items = tuple(items)
@@ -2249,6 +2250,7 @@ class Geometry(bonsai.core.tool.Geometry):
@classmethod @classmethod
def remove_linked_aggregate_data(cls, old_to_new): def remove_linked_aggregate_data(cls, old_to_new):
ifc_file = tool.Ifc.get()
for old, new in old_to_new.items(): for old, new in old_to_new.items():
pset = ifcopenshell.util.element.get_pset(new[0], "BBIM_Linked_Aggregate") pset = ifcopenshell.util.element.get_pset(new[0], "BBIM_Linked_Aggregate")
if pset: if pset:
@@ -2263,7 +2265,7 @@ class Geometry(bonsai.core.tool.Geometry):
if "BBIM_Linked_Aggregate" in r.RelatingGroup.Name if "BBIM_Linked_Aggregate" in r.RelatingGroup.Name
] ]
if linked_aggregate_group: 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 @classmethod
def name_item_object(cls, obj: bpy.types.Object, item: ifcopenshell.entity_instance) -> None: def name_item_object(cls, obj: bpy.types.Object, item: ifcopenshell.entity_instance) -> None:
+2 -2
View File
@@ -44,8 +44,8 @@ class Georeference(bonsai.core.tool.Georeference):
@classmethod @classmethod
def add_georeferencing(cls) -> None: def add_georeferencing(cls) -> None:
props = cls.get_georeference_props() props = cls.get_georeference_props()
tool.Ifc.run( ifcopenshell.api.georeference.add_georeferencing(
"georeference.add_georeferencing", tool.Ifc.get(),
ifc_class=props.coordinate_operation_class, ifc_class=props.coordinate_operation_class,
) )
+5
View File
@@ -50,6 +50,11 @@ class Ifc(bonsai.core.tool.Ifc):
@classmethod @classmethod
def run(cls, command: str, **kwargs) -> Any: 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) return ifcopenshell.api.run(command, IfcStore.get_file(), **kwargs)
@classmethod @classmethod
+19 -13
View File
@@ -51,7 +51,7 @@ class Material(bonsai.core.tool.Material):
@classmethod @classmethod
def duplicate_material(cls, material: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance: 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. # Doesn't have a name.
if new.is_a("IfcMaterialList"): if new.is_a("IfcMaterialList"):
@@ -233,18 +233,19 @@ class Material(bonsai.core.tool.Material):
def add_material_to_set( def add_material_to_set(
cls, material_set: ifcopenshell.entity_instance, material: ifcopenshell.entity_instance cls, material_set: ifcopenshell.entity_instance, material: ifcopenshell.entity_instance
) -> None: ) -> None:
ifc_file = tool.Ifc.get()
if material_set.is_a("IfcMaterialConstituentSet"): if material_set.is_a("IfcMaterialConstituentSet"):
if not material_set.MaterialConstituents: if not material_set.MaterialConstituents:
tool.Ifc.run( ifcopenshell.api.material.add_constituent(
"material.add_constituent", ifc_file,
constituent_set=material_set, constituent_set=material_set,
material=material, material=material,
) )
elif material_set.is_a() == "IfcMaterialLayerSet": elif material_set.is_a() == "IfcMaterialLayerSet":
if not material_set.MaterialLayers: if not material_set.MaterialLayers:
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file)
layer = tool.Ifc.run( layer = ifcopenshell.api.material.add_layer(
"material.add_layer", ifc_file,
layer_set=material_set, layer_set=material_set,
material=material, material=material,
) )
@@ -252,21 +253,21 @@ class Material(bonsai.core.tool.Material):
layer.LayerThickness = thickness / unit_scale layer.LayerThickness = thickness / unit_scale
elif material_set.is_a("IfcMaterialProfileSet"): elif material_set.is_a("IfcMaterialProfileSet"):
if not material_set.MaterialProfiles: 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: if named_profiles:
profile = named_profiles[0] profile = named_profiles[0]
else: 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 size = 0.5 / unit_scale
profile = tool.Ifc.get().create_entity( profile = ifc_file.create_entity(
"IfcRectangleProfileDef", "IfcRectangleProfileDef",
ProfileName="New Profile", ProfileName="New Profile",
ProfileType="AREA", ProfileType="AREA",
XDim=size, XDim=size,
YDim=size, YDim=size,
) )
material_profile = tool.Ifc.run( material_profile = ifcopenshell.api.material.add_profile(
"material.add_profile", ifc_file,
profile_set=material_set, profile_set=material_set,
material=material, material=material,
profile=profile, profile=profile,
@@ -290,6 +291,7 @@ class Material(bonsai.core.tool.Material):
def replace_material_with_material_profile( def replace_material_with_material_profile(
cls, element: ifcopenshell.entity_instance cls, element: ifcopenshell.entity_instance
) -> ifcopenshell.entity_instance: ) -> ifcopenshell.entity_instance:
ifc_file = tool.Ifc.get()
old_material = cls.get_material(element, should_inherit=False) old_material = cls.get_material(element, should_inherit=False)
old_inherited_material = cls.get_material(element, should_inherit=True) old_inherited_material = cls.get_material(element, should_inherit=True)
material = old_material if old_material and old_material.is_a("IfcMaterial") else None 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] material = tool.Ifc.get().by_type("IfcMaterial")[0]
else: else:
bonsai.core.material.unassign_material(tool.Ifc, tool.Material, objects=[tool.Ifc.get_object(element)]) 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) 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 return material_profile
@classmethod @classmethod
+1 -1
View File
@@ -1208,7 +1208,7 @@ class Model(bonsai.core.tool.Model):
if obj: if obj:
obj.matrix_world = matrix obj.matrix_world = matrix
return 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 @classmethod
def sync_object_ifc_position(cls, obj: bpy.types.Object) -> None: def sync_object_ifc_position(cls, obj: bpy.types.Object) -> None:
+11 -7
View File
@@ -27,6 +27,8 @@ import json
import time import time
import isodate import isodate
from datetime import datetime from datetime import datetime
import ifcopenshell.api.pset
import ifcopenshell.api.resource
import ifcopenshell.util.date as ifcdateutils import ifcopenshell.util.date as ifcdateutils
import ifcopenshell.util.cost import ifcopenshell.util.cost
import ifcopenshell.util.resource import ifcopenshell.util.resource
@@ -404,9 +406,10 @@ class Resource(bonsai.core.tool.Resource):
productivity = cls.get_productivity(resource) productivity = cls.get_productivity(resource)
if not productivity: if not productivity:
return return
return tool.Ifc.run( ifc_file = tool.Ifc.get()
"pset.edit_pset", return ifcopenshell.api.pset.edit_pset(
pset=tool.Ifc.get().by_id(productivity["id"]), ifc_file,
pset=ifc_file.by_id(productivity["id"]),
properties=attributes, properties=attributes,
) )
@@ -429,12 +432,13 @@ class Resource(bonsai.core.tool.Resource):
@classmethod @classmethod
def run_edit_resource_time(cls, resource: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None: def run_edit_resource_time(cls, resource: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
ifc_file = tool.Ifc.get()
if not resource.Usage: if not resource.Usage:
tool.Ifc.run( ifcopenshell.api.resource.add_resource_time(
"resource.add_resource_time", ifc_file,
resource=resource, 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 @classmethod
def go_to_resource(cls, resource: ifcopenshell.entity_instance) -> None: def go_to_resource(cls, resource: ifcopenshell.entity_instance) -> None:
@@ -459,7 +463,7 @@ class Resource(bonsai.core.tool.Resource):
@classmethod @classmethod
def run_calculate_resource_usage(cls, resource: ifcopenshell.entity_instance) -> None: 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 @classmethod
def calculate_resource_quantity(cls, resource: ifcopenshell.entity_instance) -> None: def calculate_resource_quantity(cls, resource: ifcopenshell.entity_instance) -> None:
+4 -2
View File
@@ -27,6 +27,7 @@ import mathutils
import webbrowser import webbrowser
import isodate import isodate
import ifcopenshell import ifcopenshell
import ifcopenshell.api.group
import ifcopenshell.ifcopenshell_wrapper as W import ifcopenshell.ifcopenshell_wrapper as W
import ifcopenshell.util.sequence import ifcopenshell.util.sequence
import ifcopenshell.util.date import ifcopenshell.util.date
@@ -1688,12 +1689,13 @@ class Sequence(bonsai.core.tool.Sequence):
@classmethod @classmethod
def save_animation_color_scheme(cls, name: str) -> ifcopenshell.entity_instance: def save_animation_color_scheme(cls, name: str) -> ifcopenshell.entity_instance:
props = cls.get_animation_props() props = cls.get_animation_props()
ifc_file = tool.Ifc.get()
colour_scheme = { colour_scheme = {
"Inputs": {cs.name: cs.color[0:3] for cs in props.task_input_colors}, "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}, "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: if group:
group = group[0] group = group[0]
description = json.loads(group.Description) description = json.loads(group.Description)
@@ -1701,7 +1703,7 @@ class Sequence(bonsai.core.tool.Sequence):
group.Description = json.dumps(description) group.Description = json.dumps(description)
else: else:
description = json.dumps({"type": "BBIM_AnimationColorScheme", "colourscheme": colour_scheme}) 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] return group[0]
@classmethod @classmethod
+7 -3
View File
@@ -22,6 +22,8 @@ import bmesh
import shapely import shapely
import shapely.ops import shapely.ops
import ifcopenshell import ifcopenshell
import ifcopenshell.api.attribute
import ifcopenshell.api.type
import ifcopenshell.geom import ifcopenshell.geom
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.placement import ifcopenshell.util.placement
@@ -552,7 +554,7 @@ class Spatial(bonsai.core.tool.Spatial):
@classmethod @classmethod
def edit_container_name(cls, container: ifcopenshell.entity_instance, name: str) -> None: 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 @classmethod
def get_active_container(cls) -> Union[ifcopenshell.entity_instance, None]: def get_active_container(cls) -> Union[ifcopenshell.entity_instance, None]:
@@ -1167,13 +1169,15 @@ class Spatial(bonsai.core.tool.Spatial):
@classmethod @classmethod
def assign_type_to_obj(cls, obj: bpy.types.Object) -> None: def assign_type_to_obj(cls, obj: bpy.types.Object) -> None:
props = tool.Model.get_model_props() props = tool.Model.get_model_props()
ifc_file = tool.Ifc.get()
relating_type_id = props.relating_type_id relating_type_id = props.relating_type_id
relating_type = tool.Ifc.get().by_id(int(relating_type_id)) relating_type = tool.Ifc.get().by_id(int(relating_type_id))
ifc_class = relating_type.is_a() 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) bpy.ops.bim.assign_class(obj=obj.name, ifc_class=instance_class)
element = tool.Ifc.get_entity(obj) 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 @classmethod
def assign_relating_type_to_element( def assign_relating_type_to_element(
+8 -6
View File
@@ -19,6 +19,7 @@
from __future__ import annotations from __future__ import annotations
import bpy import bpy
import ifcopenshell import ifcopenshell
import ifcopenshell.api.context
import ifcopenshell.util.representation import ifcopenshell.util.representation
import json import json
import bonsai.bim.helper import bonsai.bim.helper
@@ -67,19 +68,20 @@ class Structural(bonsai.core.tool.Structural):
@classmethod @classmethod
def ensure_representation_contexts(cls) -> None: 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: if not model:
model = tool.Ifc.run( model = ifcopenshell.api.context.add_context(
"context.add_context", ifc_file,
context_type="Model", context_type="Model",
context_identifier="", context_identifier="",
target_view="", target_view="",
parent=0, 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: if not graph:
model = tool.Ifc.run( model = ifcopenshell.api.context.add_context(
"context.add_context", ifc_file,
context_type="Model", context_type="Model",
context_identifier="Reference", context_identifier="Reference",
target_view="GRAPH_VIEW", target_view="GRAPH_VIEW",
+4 -1
View File
@@ -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: def assign_style_to_object(cls, style: ifcopenshell.entity_instance, obj: bpy.types.Object) -> None:
"""assigns `style` to `object` current representation""" """assigns `style` to `object` current representation"""
representation = tool.Geometry.get_active_representation(obj) 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 @classmethod
def assign_style_to_representation_item( def assign_style_to_representation_item(
+6 -2
View File
@@ -18,6 +18,8 @@
from __future__ import annotations from __future__ import annotations
import bpy import bpy
import ifcopenshell.api.geometry
import ifcopenshell.api.system
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.system import ifcopenshell.util.system
import bonsai.bim.helper import bonsai.bim.helper
@@ -55,11 +57,13 @@ class System(bonsai.core.tool.System):
end_port_pos: Optional[Vector] = None, end_port_pos: Optional[Vector] = None,
offset_end_port: Optional[Vector] = None, offset_end_port: Optional[Vector] = None,
) -> list[ifcopenshell.entity_instance]: ) -> list[ifcopenshell.entity_instance]:
ifc_file = tool.Ifc.get()
def add_port(mep_element, matrix): 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.FlowDirection = "NOTDEFINED"
port.PredefinedType = tool.System.get_port_predefined_type(mep_element) 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 return port
# make sure obj.dimensions and .matrix_world has valid data # make sure obj.dimensions and .matrix_world has valid data
+25 -18
View File
@@ -25,6 +25,7 @@ from ifcopenshell.util.element import get_psets, get_type, has_property
import bonsai.core.tool import bonsai.core.tool
import bonsai.tool as tool import bonsai.tool as tool
import ifcopenshell.api.sequence import ifcopenshell.api.sequence
import ifcopenshell.api.classification
import ifcopenshell.api.cost import ifcopenshell.api.cost
from typing import Any, Optional from typing import Any, Optional
import time import time
@@ -376,28 +377,30 @@ class Web(bonsai.core.tool.Web):
tool.Spatial.select_products(products, unhide=True) tool.Spatial.select_products(products, unhide=True)
if operator_data["type"] == "addSummaryCostItem": if operator_data["type"] == "addSummaryCostItem":
cost_schedule = ifc_file.by_id(operator_data["costScheduleId"]) 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) cls.load_cost_schedule_web_ui(cost_schedule)
if operator_data["type"] == "addCostItem": if operator_data["type"] == "addCostItem":
if not operator_data["costItemId"]: if not operator_data["costItemId"]:
return return
cost_item = tool.Ifc.get().by_id(operator_data["costItemId"]) 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) cost_schedule = tool.Cost.get_cost_schedule(cost_item=cost_item)
cls.load_cost_schedule_web_ui(cost_schedule) cls.load_cost_schedule_web_ui(cost_schedule)
if operator_data["type"] == "deleteCostItem": if operator_data["type"] == "deleteCostItem":
cost_item = tool.Ifc.get().by_id(operator_data["costItemId"]) cost_item = tool.Ifc.get().by_id(operator_data["costItemId"])
cost_schedule = tool.Cost.get_cost_schedule(cost_item=cost_item) 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) cls.load_cost_schedule_web_ui(cost_schedule)
if operator_data["type"] == "duplicateCostItem": if operator_data["type"] == "duplicateCostItem":
cost_item = tool.Ifc.get().by_id(operator_data["costItemId"]) cost_item = tool.Ifc.get().by_id(operator_data["costItemId"])
cost_schedule = tool.Cost.get_cost_schedule(cost_item=cost_item) 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) cls.load_cost_schedule_web_ui(cost_schedule)
if operator_data["type"] == "editCostItemName": if operator_data["type"] == "editCostItemName":
cost_item = tool.Ifc.get().by_id(operator_data["costItemId"]) 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": if operator_data["type"] == "enableEditingCostValues":
cost_item = tool.Ifc.get().by_id(operator_data["costItemId"]) cost_item = tool.Ifc.get().by_id(operator_data["costItemId"])
cost_values = ifcopenshell.util.cost.get_cost_values(cost_item) 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": if operator_data["type"] == "addSumCostValue":
cost_item = ifc_file.by_id(operator_data["costItemId"]) cost_item = ifc_file.by_id(operator_data["costItemId"])
value = tool.Ifc.run("cost.add_cost_value", parent=cost_item) value = ifcopenshell.api.cost.add_cost_value(ifc_file, parent=cost_item)
tool.Ifc.run("cost.edit_cost_value", cost_value=value, attributes={"Category": "*"}) ifcopenshell.api.cost.edit_cost_value(ifc_file, cost_value=value, attributes={"Category": "*"})
cost_schedule = tool.Cost.get_cost_schedule(cost_item=cost_item) cost_schedule = tool.Cost.get_cost_schedule(cost_item=cost_item)
cls.load_cost_schedule_web_ui(cost_schedule) cls.load_cost_schedule_web_ui(cost_schedule)
if operator_data["type"] == "deleteCostValue": if operator_data["type"] == "deleteCostValue":
cost_item = ifc_file.by_id(operator_data["costItemId"]) cost_item = ifc_file.by_id(operator_data["costItemId"])
cost_value = ifc_file.by_id(operator_data["costValueId"]) 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) cost_schedule = tool.Cost.get_cost_schedule(cost_item=cost_item)
cls.load_cost_schedule_web_ui(cost_schedule) cls.load_cost_schedule_web_ui(cost_schedule)
if operator_data["type"] == "editCostValues": if operator_data["type"] == "editCostValues":
@@ -473,7 +476,9 @@ class Web(bonsai.core.tool.Web):
cost_item_id = operator_data["costItemId"] cost_item_id = operator_data["costItemId"]
cost_item = ifc_file.by_id(cost_item_id) cost_item = ifc_file.by_id(cost_item_id)
cost_schedule = tool.Cost.get_cost_schedule(cost_item) 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_schedule_web_ui(cost_schedule)
cls.load_cost_item_quantities_ui(cost_item) cls.load_cost_item_quantities_ui(cost_item)
if operator_data["type"] == "editCostItemQuantity": 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_item = ifc_file.by_id(cost_item_id)
cost_schedule = tool.Cost.get_cost_schedule(cost_item) cost_schedule = tool.Cost.get_cost_schedule(cost_item)
physical_quantity = tool.Ifc.get().by_id(operator_data["quantityId"]) physical_quantity = tool.Ifc.get().by_id(operator_data["quantityId"])
tool.Ifc.run( ifcopenshell.api.cost.edit_cost_item_quantity(
"cost.edit_cost_item_quantity", ifc_file,
physical_quantity=physical_quantity, physical_quantity=physical_quantity,
attributes=operator_data["attributes"], attributes=operator_data["attributes"],
) )
@@ -491,7 +496,9 @@ class Web(bonsai.core.tool.Web):
if operator_data["type"] == "deleteCostItemQuantity": if operator_data["type"] == "deleteCostItemQuantity":
cost_item = ifc_file.by_id(operator_data["costItemId"]) cost_item = ifc_file.by_id(operator_data["costItemId"])
physical_quantity = ifc_file.by_id(operator_data["quantityId"]) 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) cost_schedule = tool.Cost.get_cost_schedule(cost_item)
cls.load_cost_schedule_web_ui(cost_schedule) cls.load_cost_schedule_web_ui(cost_schedule)
cls.load_cost_item_quantities_ui(cost_item) 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_item = ifc_file.by_id(operator_data["costItemId"])
cost_schedule = tool.Cost.get_cost_schedule(cost_item) cost_schedule = tool.Cost.get_cost_schedule(cost_item)
reference = ifc_file.by_id(operator_data["classificationId"]) 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) cls.load_cost_schedule_web_ui(cost_schedule)
if operator_data["type"] == "addClassificationReference": if operator_data["type"] == "addClassificationReference":
cost_item = ifc_file.by_id(operator_data["costItemId"]) cost_item = ifc_file.by_id(operator_data["costItemId"])
@@ -530,8 +537,8 @@ class Web(bonsai.core.tool.Web):
classification = element classification = element
break break
reference = IfcStore.classification_file.by_id(operator_data["classificationId"]) reference = IfcStore.classification_file.by_id(operator_data["classificationId"])
tool.Ifc.run( ifcopenshell.api.classification.add_reference(
"classification.add_reference", products=[cost_item], reference=reference, classification=classification ifc_file, products=[cost_item], reference=reference, classification=classification
) )
cls.load_cost_schedule_web_ui(cost_schedule) cls.load_cost_schedule_web_ui(cost_schedule)
if operator_data["type"] == "assignFromQuery": if operator_data["type"] == "assignFromQuery":
@@ -562,8 +569,8 @@ class Web(bonsai.core.tool.Web):
return return
products_with_quantity = [r for r in results if has_property(r, prop_name)] products_with_quantity = [r for r in results if has_property(r, prop_name)]
if products_with_quantity: if products_with_quantity:
tool.Ifc.run( ifcopenshell.api.cost.assign_cost_item_quantity(
"cost.assign_cost_item_quantity", ifc_file,
cost_item=cost_item, cost_item=cost_item,
products=results, products=results,
prop_name=prop_name, 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])) cost_schedule = tool.Cost.get_cost_schedule(ifc_file.by_id(operator_data["costItemIds"][0]))
for cost_item_id in operator_data["costItemIds"]: for cost_item_id in operator_data["costItemIds"]:
cost_item = ifc_file.by_id(cost_item_id) 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) cls.load_cost_schedule_web_ui(cost_schedule)
@classmethod @classmethod
+3 -3
View File
@@ -634,7 +634,7 @@ class TestCreateShapeAspect(NewFile):
item = ifc.createIfcExtrudedAreaSolid() item = ifc.createIfcExtrudedAreaSolid()
items = [item] items = [item]
representation = ifc.createIfcShapeRepresentation(Items=items, ContextOfItems=context) 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 product_shape = element.RepresentationMaps[0] if use_element_type else element.Representation
subject.create_shape_aspect(product_shape, representation, items, None) subject.create_shape_aspect(product_shape, representation, items, None)
@@ -653,7 +653,7 @@ class TestAddRepresentationItemToShapeAspect(NewFile):
items = [ifc.createIfcExtrudedAreaSolid(), ifc.createIfcExtrudedAreaSolid()] items = [ifc.createIfcExtrudedAreaSolid(), ifc.createIfcExtrudedAreaSolid()]
representation = ifc.createIfcShapeRepresentation(Items=items, ContextOfItems=context) 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 product_shape = element.Representation
shape_aspect0 = subject.create_shape_aspect(product_shape, representation, [items[0]], None) shape_aspect0 = subject.create_shape_aspect(product_shape, representation, [items[0]], None)
previous_shape_aspect_id = shape_aspect0.id() previous_shape_aspect_id = shape_aspect0.id()
@@ -676,7 +676,7 @@ class TestRemoveRepresentationItemFromShapeAspect(NewFile):
items = [ifc.createIfcExtrudedAreaSolid(), ifc.createIfcExtrudedAreaSolid()] items = [ifc.createIfcExtrudedAreaSolid(), ifc.createIfcExtrudedAreaSolid()]
representation = ifc.createIfcShapeRepresentation(Items=items, ContextOfItems=context) 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 product_shape = element.Representation
shape_aspect0 = subject.create_shape_aspect(product_shape, representation, [items[0]], None) shape_aspect0 = subject.create_shape_aspect(product_shape, representation, [items[0]], None)
previous_shape_aspect_id = shape_aspect0.id() previous_shape_aspect_id = shape_aspect0.id()
+19 -16
View File
@@ -19,6 +19,7 @@
import bpy import bpy
import bmesh import bmesh
import ifcopenshell import ifcopenshell
import ifcopenshell.api.style
import ifcopenshell.util.schema import ifcopenshell.util.schema
import bonsai.core.tool import bonsai.core.tool
import bonsai.tool as tool import bonsai.tool as tool
@@ -97,7 +98,9 @@ class TestCreatingStyles(NewFile):
ifc_path = Path("test/files/temp/test.ifc").absolute() ifc_path = Path("test/files/temp/test.ifc").absolute()
bpy.ops.bim.save_project(filepath=str(ifc_path), should_save_as=True) 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) material = bpy.data.materials.new(style.Name)
tool.Ifc.link(style, material) tool.Ifc.link(style, material)
get_color = lambda value: {color: value for color in ("Red", "Green", "Blue")} get_color = lambda value: {color: value for color in ("Red", "Green", "Blue")}
@@ -109,8 +112,8 @@ class TestCreatingStyles(NewFile):
"SpecularHighlight": {"IfcSpecularRoughness": 0.4}, "SpecularHighlight": {"IfcSpecularRoughness": 0.4},
"SpecularColour": 0.03, "SpecularColour": 0.03,
} }
rendering_style = tool.Ifc.run( rendering_style = ifcopenshell.api.style.add_surface_style(
"style.add_surface_style", ifc_file,
style=style, style=style,
ifc_class="IfcSurfaceStyleRendering", ifc_class="IfcSurfaceStyleRendering",
attributes=rendering_attributes, attributes=rendering_attributes,
@@ -125,9 +128,9 @@ class TestCreatingStyles(NewFile):
"uv_mode": "Generated", "uv_mode": "Generated",
} }
] ]
textures = tool.Ifc.run("style.add_surface_textures", textures=textures, uv_maps=[]) textures = ifcopenshell.api.style.add_surface_textures(ifc_file, textures=textures, uv_maps=[])
texture_style = tool.Ifc.run( texture_style = ifcopenshell.api.style.add_surface_style(
"style.add_surface_style", ifc_file,
style=style, style=style,
ifc_class="IfcSurfaceStyleWithTextures", ifc_class="IfcSurfaceStyleWithTextures",
attributes={"Textures": textures}, attributes={"Textures": textures},
@@ -162,7 +165,7 @@ class TestCreatingStyles(NewFile):
bpy.ops.bim.create_project() bpy.ops.bim.create_project()
ifc_file = tool.Ifc.get() 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) material = bpy.data.materials.new(style.Name)
tool.Ifc.link(style, material) tool.Ifc.link(style, material)
get_color = lambda value: {color: value for color in ("Red", "Green", "Blue")} get_color = lambda value: {color: value for color in ("Red", "Green", "Blue")}
@@ -174,8 +177,8 @@ class TestCreatingStyles(NewFile):
"SpecularHighlight": {"IfcSpecularRoughness": 0.4}, "SpecularHighlight": {"IfcSpecularRoughness": 0.4},
"SpecularColour": 0.03, "SpecularColour": 0.03,
} }
rendering_style = tool.Ifc.run( rendering_style = ifcopenshell.api.style.add_surface_style(
"style.add_surface_style", ifc_file,
style=style, style=style,
ifc_class="IfcSurfaceStyleRendering", ifc_class="IfcSurfaceStyleRendering",
attributes=rendering_attributes, attributes=rendering_attributes,
@@ -239,8 +242,8 @@ class TestCreatingStyles(NewFile):
# setup UV # setup UV
ifc_file.create_entity("IfcTextureCoordinateGenerator", Maps=textures, Mode="COORD") ifc_file.create_entity("IfcTextureCoordinateGenerator", Maps=textures, Mode="COORD")
texture_style = tool.Ifc.run( texture_style = ifcopenshell.api.style.add_surface_style(
"style.add_surface_style", ifc_file,
style=style, style=style,
ifc_class="IfcSurfaceStyleWithTextures", ifc_class="IfcSurfaceStyleWithTextures",
attributes={"Textures": textures}, attributes={"Textures": textures},
@@ -332,7 +335,7 @@ class TestCreatingStyles(NewFile):
bpy.ops.bim.create_project() bpy.ops.bim.create_project()
ifc_file = tool.Ifc.get() 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) material = bpy.data.materials.new(style.Name)
tool.Ifc.link(style, material) tool.Ifc.link(style, material)
get_color = lambda value: {color: value for color in ("Red", "Green", "Blue")} get_color = lambda value: {color: value for color in ("Red", "Green", "Blue")}
@@ -344,8 +347,8 @@ class TestCreatingStyles(NewFile):
"SpecularHighlight": {"IfcSpecularRoughness": 0.4}, "SpecularHighlight": {"IfcSpecularRoughness": 0.4},
"SpecularColour": 0.03, "SpecularColour": 0.03,
} }
rendering_style = tool.Ifc.run( rendering_style = ifcopenshell.api.style.add_surface_style(
"style.add_surface_style", ifc_file,
style=style, style=style,
ifc_class="IfcSurfaceStyleRendering", ifc_class="IfcSurfaceStyleRendering",
attributes=rendering_attributes, attributes=rendering_attributes,
@@ -374,8 +377,8 @@ class TestCreatingStyles(NewFile):
# setup UV # setup UV
ifc_file.create_entity("IfcTextureCoordinateGenerator", Maps=textures, Mode="COORD") ifc_file.create_entity("IfcTextureCoordinateGenerator", Maps=textures, Mode="COORD")
texture_style = tool.Ifc.run( texture_style = ifcopenshell.api.style.add_surface_style(
"style.add_surface_style", ifc_file,
style=style, style=style,
ifc_class="IfcSurfaceStyleWithTextures", ifc_class="IfcSurfaceStyleWithTextures",
attributes={"Textures": textures}, attributes={"Textures": textures},
+2 -2
View File
@@ -76,7 +76,7 @@ class TestGetBooleans(NewFile):
items = [ifc.createIfcExtrudedAreaSolid()] items = [ifc.createIfcExtrudedAreaSolid()]
representation = ifc.createIfcShapeRepresentation(Items=items, ContextOfItems=context) 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) builder = ifcopenshell.util.shape_builder.ShapeBuilder(ifc)
cut1 = builder.half_space_solid(builder.plane()) cut1 = builder.half_space_solid(builder.plane())
@@ -96,7 +96,7 @@ class TestGetManualBooleans(NewFile):
items = [ifc.createIfcExtrudedAreaSolid()] items = [ifc.createIfcExtrudedAreaSolid()]
representation = ifc.createIfcShapeRepresentation(Items=items, ContextOfItems=context) 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) builder = ifcopenshell.util.shape_builder.ShapeBuilder(ifc)
cut1 = builder.half_space_solid(builder.plane()) cut1 = builder.half_space_solid(builder.plane())