From 8b4683aef1a3624f10be2ddcf0b3c75d996c9ae1 Mon Sep 17 00:00:00 2001 From: Andrej Date: Mon, 9 Jun 2025 10:59:22 +0500 Subject: [PATCH] replace api.run with static methods --- src/bonsai/bonsai/bim/handler.py | 3 +- .../bonsai/bim/module/aggregate/operator.py | 7 +- .../bonsai/bim/module/boundary/operator.py | 3 +- src/bonsai/bonsai/bim/module/bsdd/operator.py | 5 +- .../bim/module/classification/operator.py | 51 +- src/bonsai/bonsai/bim/module/cost/operator.py | 6 +- src/bonsai/bonsai/bim/module/csv/operator.py | 1 + .../bonsai/bim/module/drawing/decoration.py | 1 + .../bonsai/bim/module/drawing/operator.py | 6 +- src/bonsai/bonsai/bim/module/drawing/prop.py | 8 +- .../bonsai/bim/module/drawing/scheduler.py | 2 + .../bonsai/bim/module/drawing/svgwriter.py | 1 + .../bonsai/bim/module/drawing/workspace.py | 1 + .../bonsai/bim/module/geometry/operator.py | 30 +- .../bonsai/bim/module/group/operator.py | 10 +- .../bonsai/bim/module/light/__init__.py | 1 + .../bonsai/bim/module/light/operator.py | 2 + .../bonsai/bim/module/material/operator.py | 22 +- src/bonsai/bonsai/bim/module/model/array.py | 6 +- src/bonsai/bonsai/bim/module/model/door.py | 24 +- src/bonsai/bonsai/bim/module/model/mep.py | 35 +- src/bonsai/bonsai/bim/module/model/opening.py | 51 +- src/bonsai/bonsai/bim/module/model/product.py | 7 +- src/bonsai/bonsai/bim/module/model/profile.py | 63 +-- src/bonsai/bonsai/bim/module/model/railing.py | 17 +- src/bonsai/bonsai/bim/module/model/roof.py | 7 +- src/bonsai/bonsai/bim/module/model/slab.py | 39 +- src/bonsai/bonsai/bim/module/model/stair.py | 16 +- .../bim/module/model/sverchok_modifier.py | 7 +- src/bonsai/bonsai/bim/module/model/task.py | 8 +- src/bonsai/bonsai/bim/module/model/wall.py | 48 +- src/bonsai/bonsai/bim/module/model/window.py | 21 +- .../bonsai/bim/module/project/operator.py | 4 +- src/bonsai/bonsai/bim/module/pset/operator.py | 24 +- .../bim/module/pset_template/operator.py | 19 +- src/bonsai/bonsai/bim/module/root/operator.py | 28 +- .../bonsai/bim/module/search/operator.py | 8 +- .../bonsai/bim/module/structural/operator.py | 26 +- .../bonsai/bim/module/style/operator.py | 18 +- .../bonsai/bim/module/system/operator.py | 7 +- src/bonsai/bonsai/bim/module/void/operator.py | 11 +- src/bonsai/bonsai/bim/operator.py | 1 + src/bonsai/bonsai/tool/cost.py | 6 +- src/bonsai/bonsai/tool/drawing.py | 15 +- src/bonsai/bonsai/tool/feature.py | 5 +- src/bonsai/bonsai/tool/geometry.py | 3 +- src/bonsai/bonsai/tool/ifcgit.py | 4 + src/bonsai/bonsai/tool/model.py | 29 +- src/bonsai/bonsai/tool/pset_template.py | 1 + src/bonsai/bonsai/tool/root.py | 24 +- .../docs/guides/development/hello_world.rst | 8 +- .../docs/guides/development/undo_system.rst | 2 +- src/bonsai/scripts/bonsai_translations.py | 6 +- src/bonsai/scripts/extract.py | 2 +- src/bonsai/scripts/gbxml.py | 5 +- src/bonsai/scripts/generate_au_library.py | 90 ++-- .../scripts/generate_entourage_library.py | 62 ++- .../scripts/generate_furniture_library.py | 112 ++--- .../scripts/generate_landscape_library.py | 75 ++- src/bonsai/scripts/generate_site_library.py | 50 +- .../generate_steel_profiles_library.py | 36 +- .../scripts/geonodes_modifier_prototype.py | 7 +- src/bonsai/scripts/obj2ifc-meshlab.py | 56 +-- src/bonsai/scripts/obj2ifc.py | 56 +-- src/bonsai/scripts/replace_drawing_path.py | 5 +- src/bonsai/scripts/shape_builder_examples.py | 69 +-- .../scripts/standalone_blender_import.py | 3 +- src/bonsai/scripts/standalone_drawer.py | 1 + src/bonsai/scripts/waldo.py | 14 +- src/bonsai/test/tool/test_aggregate.py | 5 +- src/bonsai/test/tool/test_brick.py | 12 +- src/bonsai/test/tool/test_document.py | 11 +- src/bonsai/test/tool/test_drawing.py | 31 +- src/bonsai/test/tool/test_geometry.py | 17 +- src/bonsai/test/tool/test_georeference.py | 74 +-- src/bonsai/test/tool/test_material.py | 7 +- src/bonsai/test/tool/test_misc.py | 33 +- src/bonsai/test/tool/test_model.py | 3 +- src/bonsai/test/tool/test_nest.py | 4 +- src/bonsai/test/tool/test_patch.py | 1 + src/bonsai/test/tool/test_project.py | 9 +- src/bonsai/test/tool/test_pset.py | 10 +- src/bonsai/test/tool/test_qto.py | 27 +- src/bonsai/test/tool/test_root.py | 8 +- src/bonsai/test/tool/test_spatial.py | 10 +- src/bonsai/test/tool/test_style.py | 3 +- src/bonsai/test/tool/test_surveyor.py | 8 +- src/bonsai/test/tool/test_system.py | 24 +- src/bonsai/test/tool/test_type.py | 2 +- src/bsdd/bsdd.py | 14 +- src/ifc4d/ifc4d/common.py | 96 ++-- src/ifc4d/ifc4d/csv2ifc.py | 23 +- src/ifc4d/ifc4d/csv4d2ifc.py | 26 +- src/ifc4d/ifc4d/msp2ifc.py | 73 ++- .../ifccityjson/cityjson2ifc/cityjson2ifc.py | 29 +- src/ifcdiff/test.py | 7 +- .../test_add_stationing_to_alignment.py | 1 + .../test/api/context/test_remove_context.py | 2 + .../test/api/feature/test_add_feature.py | 1 + .../test/api/geometry/test_add_boolean.py | 1 + .../test/api/geometry/test_remove_boolean.py | 1 + .../test/api/geometry/test_validate_type.py | 1 + .../api/owner/test_update_owner_history.py | 4 + src/ifcopenshell-python/test/file_gc.py | 2 + src/ifcopenshell-python/test/geom/settings.py | 8 +- src/ifcopenshell-python/test/test_stream.py | 4 + src/ifcopenshell-python/test/test_write.py | 2 + .../test/util/test_shape_builder.py | 10 +- src/ifcpatch/test/bootstrap.py | 7 +- src/ifcpatch/test/test_ExtractElements.py | 39 +- src/ifcpatch/test/test_MergeDuplicateTypes.py | 26 +- src/ifcpatch/test/test_MergeProject.py | 12 +- src/ifcpatch/test/test_RegenerateGlobalIds.py | 11 +- src/ifcsverchok/__init__.py | 21 +- src/ifcsverchok/ifcstore.py | 4 +- .../nodes/ifc/add_spatial_element.py | 26 +- src/ifcsverchok/nodes/ifc/bmesh_to_ifc.py | 16 +- src/ifcsverchok/nodes/ifc/create_project.py | 14 +- src/ifcsverchok/nodes/ifc/write_file.py | 19 +- src/ifctester/test/ids_doc_generator.py | 57 ++- src/ifctester/test/test_facet.py | 445 +++++++++--------- src/ifctester/test/test_ids.py | 2 + 122 files changed, 1334 insertions(+), 1370 deletions(-) diff --git a/src/bonsai/bonsai/bim/handler.py b/src/bonsai/bonsai/bim/handler.py index 9e6a5529f4..21cfd08adb 100644 --- a/src/bonsai/bonsai/bim/handler.py +++ b/src/bonsai/bonsai/bim/handler.py @@ -263,8 +263,7 @@ def get_application(ifc: ifcopenshell.file) -> ifcopenshell.entity_instance: for element in ifc.by_type("IfcApplication"): if element.ApplicationIdentifier == "Bonsai" and element.Version == version: return element - return ifcopenshell.api.run( - "owner.add_application", + return ifcopenshell.api.owner.add_application( ifc, version=version, application_full_name="Bonsai", diff --git a/src/bonsai/bonsai/bim/module/aggregate/operator.py b/src/bonsai/bonsai/bim/module/aggregate/operator.py index 08fac65030..9c7b23fcc7 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.pset import ifcopenshell.util.element import bonsai.tool as tool import bonsai.core.aggregate as core @@ -112,7 +113,7 @@ class BIM_OT_aggregate_unassign_object(bpy.types.Operator, tool.Ifc.Operator): pset = ifcopenshell.util.element.get_pset(element, "BBIM_Linked_Aggregate") if pset: pset = tool.Ifc.get().by_id(pset["id"]) - ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), product=element, pset=pset) + ifcopenshell.api.pset.remove_pset(tool.Ifc.get(), product=element, pset=pset) class BIM_OT_enable_editing_aggregate(bpy.types.Operator): @@ -312,7 +313,7 @@ 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.run("pset.remove_pset", tool.Ifc.get(), product=part, pset=pset) + ifcopenshell.api.pset.remove_pset(tool.Ifc.get(), product=part, pset=pset) linked_aggregate_group = next( r.RelatingGroup @@ -385,7 +386,7 @@ class BIM_OT_disable_aggregate_mode(bpy.types.Operator): def execute(self, context): bpy.ops.object.select_all(action="DESELECT") - bonsai.core.aggregate.exit_aggregate_mode(tool.Aggregate) + core.exit_aggregate_mode(tool.Aggregate) return {"FINISHED"} diff --git a/src/bonsai/bonsai/bim/module/boundary/operator.py b/src/bonsai/bonsai/bim/module/boundary/operator.py index d9958a80db..91fed71e92 100644 --- a/src/bonsai/bonsai/bim/module/boundary/operator.py +++ b/src/bonsai/bonsai/bim/module/boundary/operator.py @@ -404,12 +404,13 @@ class EditBoundaryAttributes(bpy.types.Operator, tool.Ifc.Operator): assert obj bprops = tool.Boundary.get_object_boundary_props(obj) boundary = tool.Ifc.get_entity(obj) + assert boundary attributes = dict() for ifc_attribute, blender_property in EDITABLE_ATTRIBUTES.items(): obj = getattr(bprops, blender_property, None) entity = tool.Ifc.get_entity(obj) attributes[blender_property] = entity - ifcopenshell.api.run("boundary.edit_attributes", tool.Ifc.get(), entity=boundary, **attributes) + ifcopenshell.api.boundary.edit_attributes(tool.Ifc.get(), entity=boundary, **attributes) bpy.ops.bim.disable_editing_boundary() return {"FINISHED"} diff --git a/src/bonsai/bonsai/bim/module/bsdd/operator.py b/src/bonsai/bonsai/bim/module/bsdd/operator.py index 111c64c40d..b9161b3d40 100644 --- a/src/bonsai/bonsai/bim/module/bsdd/operator.py +++ b/src/bonsai/bonsai/bim/module/bsdd/operator.py @@ -19,6 +19,7 @@ import bpy import bsdd import bonsai.tool as tool +import ifcopenshell.api.pset import ifcopenshell.util.element from bonsai.core import bsdd as core @@ -101,5 +102,5 @@ class AddBSDDProperties(bpy.types.Operator, tool.Ifc.Operator): if pset := current_psets.get(pset_name, None): pset = self.file.by_id(pset["id"]) else: - pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name=pset_name) - ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties=properties) + pset = ifcopenshell.api.pset.add_pset(self.file, product=element, name=pset_name) + ifcopenshell.api.pset.edit_pset(self.file, pset=pset, properties=properties) diff --git a/src/bonsai/bonsai/bim/module/classification/operator.py b/src/bonsai/bonsai/bim/module/classification/operator.py index 13d973a8a6..bead1b8d6a 100644 --- a/src/bonsai/bonsai/bim/module/classification/operator.py +++ b/src/bonsai/bonsai/bim/module/classification/operator.py @@ -20,6 +20,7 @@ import bpy import json import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.pset import ifcopenshell.api.classification import ifcopenshell.util.classification import ifcopenshell.util.element @@ -47,8 +48,7 @@ class AddClassification(bpy.types.Operator, tool.Ifc.Operator): def _execute(self, context): props = context.scene.BIMClassificationProperties - ifcopenshell.api.run( - "classification.add_classification", + ifcopenshell.api.classification.add_classification( tool.Ifc.get(), classification=IfcStore.classification_file.by_id(int(props.available_classifications)), ) @@ -62,11 +62,9 @@ class AddManualClassification(bpy.types.Operator, tool.Ifc.Operator): def _execute(self, context): props = context.scene.BIMClassificationProperties attributes = bonsai.bim.helper.export_attributes(props.classification_attributes) - classification = ifcopenshell.api.run( - "classification.add_classification", tool.Ifc.get(), classification="Unnamed" - ) - ifcopenshell.api.run( - "classification.edit_classification", tool.Ifc.get(), classification=classification, attributes=attributes + classification = ifcopenshell.api.classification.add_classification(tool.Ifc.get(), classification="Unnamed") + ifcopenshell.api.classification.edit_classification( + tool.Ifc.get(), classification=classification, attributes=attributes ) props.is_adding = False @@ -95,17 +93,14 @@ class AddManualClassificationReference(bpy.types.Operator, tool.Ifc.Operator): ] if products: classification = tool.Ifc.get().by_id(int(props.classifications)) - reference = ifcopenshell.api.run( - "classification.add_reference", + reference = ifcopenshell.api.classification.add_reference( tool.Ifc.get(), products=products, classification=classification, identification="X", name="Unnamed", ) - ifcopenshell.api.run( - "classification.edit_reference", tool.Ifc.get(), reference=reference, attributes=attributes - ) + ifcopenshell.api.classification.edit_reference(tool.Ifc.get(), reference=reference, attributes=attributes) props.is_adding = False @@ -133,8 +128,8 @@ class AddClassificationFromBSDD(bpy.types.Operator, tool.Ifc.Operator): has_classification = True if has_classification: continue - classification = ifcopenshell.api.run( - "classification.add_classification", tool.Ifc.get(), classification=dictionary["name"] + classification = ifcopenshell.api.classification.add_classification( + tool.Ifc.get(), classification=dictionary["name"] ) classification.Source = dictionary["organizationNameOwner"] classification.Edition = dictionary["version"] @@ -239,8 +234,7 @@ class RemoveClassification(bpy.types.Operator, tool.Ifc.Operator): def _execute(self, context): self.file = tool.Ifc.get() - ifcopenshell.api.run( - "classification.remove_classification", + ifcopenshell.api.classification.remove_classification( tool.Ifc.get(), classification=self.file.by_id(self.classification), ) @@ -329,8 +323,7 @@ class RemoveClassificationReference(bpy.types.Operator, tool.Ifc.Operator): if elements_by_references: for reference, products in elements_by_references.items(): - ifcopenshell.api.run( - "classification.remove_reference", + ifcopenshell.api.classification.remove_reference( tool.Ifc.get(), reference=reference, products=products, @@ -385,8 +378,7 @@ class AddClassificationReference(bpy.types.Operator, tool.Ifc.Operator): if (ifc_definition_id := tool.Blender.get_obj_ifc_definition_id(obj, self.obj_type, context)) ] if products: - ifcopenshell.api.run( - "classification.add_reference", + ifcopenshell.api.classification.add_reference( tool.Ifc.get(), reference=IfcStore.classification_file.by_id(self.reference), products=products, @@ -428,8 +420,8 @@ class AddClassificationReferenceFromBSDD(bpy.types.Operator, tool.Ifc.Operator): break if not classification: - classification = ifcopenshell.api.run( - "classification.add_classification", tool.Ifc.get(), classification=bsdd_classification.dictionary_name + classification = ifcopenshell.api.classification.add_classification( + tool.Ifc.get(), classification=bsdd_classification.dictionary_name ) tool.Classification.set_location(classification, bsdd_classification.dictionary_namespace_uri) @@ -438,8 +430,7 @@ class AddClassificationReferenceFromBSDD(bpy.types.Operator, tool.Ifc.Operator): if not ifc_definition_id: continue element = tool.Ifc.get().by_id(ifc_definition_id) - reference = ifcopenshell.api.run( - "classification.add_reference", + reference = ifcopenshell.api.classification.add_reference( tool.Ifc.get(), products=[element], classification=classification, @@ -477,18 +468,16 @@ class AddClassificationReferenceFromBSDD(bpy.types.Operator, tool.Ifc.Operator): if pset: pset = tool.Ifc.get().by_id(pset["id"]) elif is_pset: - pset = ifcopenshell.api.run( - "pset.add_pset", tool.Ifc.get(), product=element, name=classification_pset.name + pset = ifcopenshell.api.pset.add_pset( + tool.Ifc.get(), product=element, name=classification_pset.name ) else: - pset = ifcopenshell.api.run( - "pset.add_qto", tool.Ifc.get(), product=element, name=classification_pset.name - ) + pset = ifcopenshell.api.pset.add_qto(tool.Ifc.get(), product=element, name=classification_pset.name) if is_pset: - ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties=properties) + ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties=properties) else: - ifcopenshell.api.run("pset.edit_qto", tool.Ifc.get(), qto=pset, properties=properties) + ifcopenshell.api.pset.edit_qto(tool.Ifc.get(), qto=pset, properties=properties) class ChangeClassificationLevel(bpy.types.Operator): diff --git a/src/bonsai/bonsai/bim/module/cost/operator.py b/src/bonsai/bonsai/bim/module/cost/operator.py index 37f5c5e1f8..3a273a0fe0 100644 --- a/src/bonsai/bonsai/bim/module/cost/operator.py +++ b/src/bonsai/bonsai/bim/module/cost/operator.py @@ -20,12 +20,11 @@ import bpy import textwrap -import ifcopenshell.api +import ifcopenshell.api.nest import bonsai.tool as tool from bpy_extras.io_utils import ImportHelper, ExportHelper import bonsai.tool as tool import bonsai.core.cost as core -from pathlib import Path from typing import get_args, TYPE_CHECKING, Literal @@ -847,8 +846,7 @@ class ReorderCostItem(bpy.types.Operator, tool.Ifc.Operator): cost_item: bpy.props.IntProperty() def _execute(self, context): - ifcopenshell.api.run( - "nest.reorder_nesting", + ifcopenshell.api.nest.reorder_nesting( tool.Ifc.get(), **{ "item": tool.Ifc.get().by_id(self.cost_item), diff --git a/src/bonsai/bonsai/bim/module/csv/operator.py b/src/bonsai/bonsai/bim/module/csv/operator.py index c705ab90f2..618c022cf4 100644 --- a/src/bonsai/bonsai/bim/module/csv/operator.py +++ b/src/bonsai/bonsai/bim/module/csv/operator.py @@ -312,6 +312,7 @@ class ImportIfcCsv(bpy.types.Operator, tool.Ifc.Operator, ImportHelper): import ifccsv props = tool.Blender.get_csv_props() + ifc_file: ifcopenshell.file if props.should_load_from_memory: ifc_file = tool.Ifc.get() else: diff --git a/src/bonsai/bonsai/bim/module/drawing/decoration.py b/src/bonsai/bonsai/bim/module/drawing/decoration.py index fad54c3059..627615b581 100644 --- a/src/bonsai/bonsai/bim/module/drawing/decoration.py +++ b/src/bonsai/bonsai/bim/module/drawing/decoration.py @@ -24,6 +24,7 @@ import bmesh import shapely import ifcopenshell import ifcopenshell.util.element +import ifcopenshell.util.representation import ifcopenshell.util.unit import bonsai.tool as tool import bonsai.bim.module.drawing.helper as helper diff --git a/src/bonsai/bonsai/bim/module/drawing/operator.py b/src/bonsai/bonsai/bim/module/drawing/operator.py index d000a6c4b8..803c1c6864 100644 --- a/src/bonsai/bonsai/bim/module/drawing/operator.py +++ b/src/bonsai/bonsai/bim/module/drawing/operator.py @@ -24,6 +24,7 @@ import bmesh import shutil import hashlib import shapely +import shapely.ops import subprocess import numpy as np import multiprocessing @@ -34,9 +35,10 @@ import ifcopenshell.api.pset import ifcopenshell.api.style import ifcopenshell.ifcopenshell_wrapper import ifcopenshell.geom -import ifcopenshell.util.selector -import ifcopenshell.util.representation import ifcopenshell.util.element +import ifcopenshell.util.representation +import ifcopenshell.util.selector +import ifcopenshell.util.unit import bonsai.bim.helper import bonsai.bim.handler import bonsai.tool as tool diff --git a/src/bonsai/bonsai/bim/module/drawing/prop.py b/src/bonsai/bonsai/bim/module/drawing/prop.py index 3a2fbe7fa7..80a04706ab 100644 --- a/src/bonsai/bonsai/bim/module/drawing/prop.py +++ b/src/bonsai/bonsai/bim/module/drawing/prop.py @@ -119,8 +119,8 @@ def update_is_nts(self: "BIMCameraProperties", context: bpy.types.Context) -> No if pset: pset = tool.Ifc.get().by_id(pset["id"]) else: - pset = ifcopenshell.api.run("pset.add_pset", tool.Ifc.get(), product=element, name="EPset_Drawing") - ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties={"IsNTS": self.is_nts}) + pset = ifcopenshell.api.pset.add_pset(tool.Ifc.get(), product=element, name="EPset_Drawing") + ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties={"IsNTS": self.is_nts}) def get_diagram_scales(self: "BIMCameraProperties", context: bpy.types.Context) -> list[tuple[str, str, str]]: @@ -250,8 +250,8 @@ def update_layer(self: "BIMCameraProperties", context: bpy.types.Context, name: if pset: pset = tool.Ifc.get().by_id(pset["id"]) else: - pset = ifcopenshell.api.run("pset.add_pset", tool.Ifc.get(), product=element, name="EPset_Drawing") - ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties={name: value}) + pset = ifcopenshell.api.pset.add_pset(tool.Ifc.get(), product=element, name="EPset_Drawing") + ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties={name: value}) def get_titleblocks(self, context): diff --git a/src/bonsai/bonsai/bim/module/drawing/scheduler.py b/src/bonsai/bonsai/bim/module/drawing/scheduler.py index 00ce2c1612..ce2b711071 100644 --- a/src/bonsai/bonsai/bim/module/drawing/scheduler.py +++ b/src/bonsai/bonsai/bim/module/drawing/scheduler.py @@ -22,6 +22,8 @@ import bpy import string import svgwrite import openpyxl +import openpyxl.cell # Unnecessary, bug in typeshed. +import openpyxl.utils # Unnecessary, bug in typeshed. import bonsai.tool as tool from bonsai.bim.module.drawing.svgwriter import SvgWriter diff --git a/src/bonsai/bonsai/bim/module/drawing/svgwriter.py b/src/bonsai/bonsai/bim/module/drawing/svgwriter.py index da8050cd44..f6e1cda3e1 100644 --- a/src/bonsai/bonsai/bim/module/drawing/svgwriter.py +++ b/src/bonsai/bonsai/bim/module/drawing/svgwriter.py @@ -26,6 +26,7 @@ from bpy.types import SplineBezierPoints, SplinePoints import mathutils import xml.etree.ElementTree as ET import svgwrite +import svgwrite.container import svgwrite.text import ifcopenshell import ifcopenshell.util.element diff --git a/src/bonsai/bonsai/bim/module/drawing/workspace.py b/src/bonsai/bonsai/bim/module/drawing/workspace.py index b65d68e53b..778898b2c0 100644 --- a/src/bonsai/bonsai/bim/module/drawing/workspace.py +++ b/src/bonsai/bonsai/bim/module/drawing/workspace.py @@ -20,6 +20,7 @@ import os import bpy import ifcopenshell.util.element +import bonsai.core.geometry import bonsai.core.type import bonsai.core.drawing as core import bonsai.tool as tool diff --git a/src/bonsai/bonsai/bim/module/geometry/operator.py b/src/bonsai/bonsai/bim/module/geometry/operator.py index b8567d489e..4f1bf4c2db 100644 --- a/src/bonsai/bonsai/bim/module/geometry/operator.py +++ b/src/bonsai/bonsai/bim/module/geometry/operator.py @@ -22,6 +22,8 @@ import bmesh import numpy as np import numpy.typing as npt import ifcopenshell +import ifcopenshell.api.group +import ifcopenshell.api.pset import ifcopenshell.api.geometry import ifcopenshell.api.layer import ifcopenshell.api.material @@ -754,10 +756,10 @@ class CopyRepresentation(bpy.types.Operator, tool.Ifc.Operator): bm.to_mesh(obj.data) old_rep = tool.Geometry.get_representation_by_context(element, geometric_context) if old_rep: - ifcopenshell.api.run( - "geometry.unassign_representation", tool.Ifc.get(), product=element, representation=old_rep + ifcopenshell.api.geometry.unassign_representation( + tool.Ifc.get(), product=element, representation=old_rep ) - ifcopenshell.api.run("geometry.remove_representation", tool.Ifc.get(), representation=old_rep) + ifcopenshell.api.geometry.remove_representation(tool.Ifc.get(), representation=old_rep) core.add_representation( tool.Ifc, tool.Geometry, @@ -1183,10 +1185,9 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator): pset = ifcopenshell.util.element.get_pset(part, self.pset_name) if not pset: - pset = ifcopenshell.api.run("pset.add_pset", tool.Ifc.get(), product=part, name=self.pset_name) + pset = ifcopenshell.api.pset.add_pset(tool.Ifc.get(), product=part, name=self.pset_name) - ifcopenshell.api.run( - "pset.edit_pset", + ifcopenshell.api.pset.edit_pset( tool.Ifc.get(), pset=pset, properties={"Index": index}, @@ -1208,8 +1209,8 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator): if self.group_name in product_groups_name: return - linked_aggregate_group = ifcopenshell.api.run("group.add_group", tool.Ifc.get(), name=self.group_name) - ifcopenshell.api.run("group.assign_group", tool.Ifc.get(), products=[element], group=linked_aggregate_group) + 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) def custom_incremental_naming_for_element_assembly(old_to_new): for new in old_to_new.values(): @@ -1247,12 +1248,9 @@ 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.run( - "pset.add_pset", tool.Ifc.get(), product=new[0], name=self.pset_name - ) + new_pset = ifcopenshell.api.pset.add_pset(tool.Ifc.get(), product=new[0], name=self.pset_name) - ifcopenshell.api.run( - "pset.edit_pset", + ifcopenshell.api.pset.edit_pset( tool.Ifc.get(), pset=new_pset, properties={"Index": pset["Index"]}, @@ -2237,8 +2235,7 @@ class OverrideModeSetObject(bpy.types.Operator, tool.Ifc.Operator): curves.append(profile.OuterCurve) if profile.is_a("IfcArbitraryProfileDefWithVoids"): curves.extend(profile.InnerCurves) - new_footprint = ifcopenshell.api.run( - "geometry.add_footprint_representation", + new_footprint = ifcopenshell.api.geometry.add_footprint_representation( tool.Ifc.get(), context=footprint_context, curves=curves, @@ -2253,8 +2250,7 @@ class OverrideModeSetObject(bpy.types.Operator, tool.Ifc.Operator): tool.Ifc, tool.Geometry, obj=obj, representation=old_footprint ) else: - ifcopenshell.api.run( - "geometry.assign_representation", + ifcopenshell.api.geometry.assign_representation( tool.Ifc.get(), product=element, representation=new_footprint, diff --git a/src/bonsai/bonsai/bim/module/group/operator.py b/src/bonsai/bonsai/bim/module/group/operator.py index c82eb0d055..bc017edec7 100644 --- a/src/bonsai/bonsai/bim/module/group/operator.py +++ b/src/bonsai/bonsai/bim/module/group/operator.py @@ -19,7 +19,7 @@ import bpy import ifcopenshell.api import ifcopenshell.api.group -import ifcopenshell.util.attribute +import ifcopenshell.util.element import bonsai.bim.helper import bonsai.tool as tool import json @@ -108,10 +108,10 @@ class AddGroup(bpy.types.Operator, tool.Ifc.Operator): group: bpy.props.IntProperty() def _execute(self, context): - result = ifcopenshell.api.run("group.add_group", tool.Ifc.get()) + result = ifcopenshell.api.group.add_group(tool.Ifc.get()) if self.group: - ifcopenshell.api.run( - "group.assign_group", tool.Ifc.get(), products=[result], group=tool.Ifc.get().by_id(self.group) + ifcopenshell.api.group.assign_group( + tool.Ifc.get(), products=[result], group=tool.Ifc.get().by_id(self.group) ) bpy.ops.bim.load_groups() return {"FINISHED"} @@ -139,7 +139,7 @@ class RemoveGroup(bpy.types.Operator, tool.Ifc.Operator): def _execute(self, context): self.file = tool.Ifc.get() - ifcopenshell.api.run("group.remove_group", self.file, **{"group": self.file.by_id(self.group)}) + ifcopenshell.api.group.remove_group(self.file, **{"group": self.file.by_id(self.group)}) bpy.ops.bim.load_groups() return {"FINISHED"} diff --git a/src/bonsai/bonsai/bim/module/light/__init__.py b/src/bonsai/bonsai/bim/module/light/__init__.py index 04bd22a80c..ff44498927 100644 --- a/src/bonsai/bonsai/bim/module/light/__init__.py +++ b/src/bonsai/bonsai/bim/module/light/__init__.py @@ -23,6 +23,7 @@ import stat from pathlib import Path import importlib +import importlib.util import pyradiance diff --git a/src/bonsai/bonsai/bim/module/light/operator.py b/src/bonsai/bonsai/bim/module/light/operator.py index bc7c571d9d..9d02146036 100644 --- a/src/bonsai/bonsai/bim/module/light/operator.py +++ b/src/bonsai/bonsai/bim/module/light/operator.py @@ -34,6 +34,7 @@ import json import math import time import ifcopenshell +import ifcopenshell.util.geolocation import webbrowser import ifcopenshell.geom import multiprocessing @@ -80,6 +81,7 @@ class ExportOBJ(bpy.types.Operator): serializer_settings.set("use-element-guids", True) settings.set("use-world-coords", True) + ifc_file: ifcopenshell.file if should_load_from_memory: ifc_file = tool.Ifc.get() diff --git a/src/bonsai/bonsai/bim/module/material/operator.py b/src/bonsai/bonsai/bim/module/material/operator.py index 08c3e161b3..1f8626bd7c 100644 --- a/src/bonsai/bonsai/bim/module/material/operator.py +++ b/src/bonsai/bonsai/bim/module/material/operator.py @@ -20,13 +20,12 @@ import bpy import json import ifcopenshell.api import ifcopenshell.api.material +import ifcopenshell.api.profile +import ifcopenshell.api.style import ifcopenshell.util.element -import ifcopenshell.util.attribute import ifcopenshell.util.representation -import ifcopenshell.util.unit import bonsai.bim.helper import bonsai.tool as tool -import bonsai.core.style import bonsai.core.material as core import bonsai.bim.module.model.profile as model_profile from typing import Any, Union, TYPE_CHECKING @@ -121,13 +120,11 @@ class AssignParameterizedProfile(bpy.types.Operator, tool.Ifc.Operator): def _execute(self, context): obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object self.file = tool.Ifc.get() - profile = ifcopenshell.api.run( - "profile.add_parameterized_profile", + profile = ifcopenshell.api.profile.add_parameterized_profile( self.file, **{"ifc_class": self.ifc_class}, ) - ifcopenshell.api.run( - "material.assign_profile", + ifcopenshell.api.material.assign_profile( self.file, **{"material_profile": self.file.by_id(self.material_profile), "profile": profile}, ) @@ -472,8 +469,7 @@ class RemoveListItem(bpy.types.Operator, tool.Ifc.Operator): def _execute(self, context): obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object self.file = tool.Ifc.get() - ifcopenshell.api.run( - "material.remove_list_item", + ifcopenshell.api.material.remove_list_item( self.file, **{ "material_list": self.file.by_id(self.list_item_set), @@ -683,7 +679,7 @@ class EditMaterialSetItemProfile(bpy.types.Operator, tool.Ifc.Operator): self.props = tool.Material.get_object_material_props(obj) attributes = bonsai.bim.helper.export_attributes(self.props.material_set_item_profile_attributes) profile = tool.Ifc.get().by_id(self.material_set_item).Profile - ifcopenshell.api.run("profile.edit_profile", tool.Ifc.get(), profile=profile, attributes=attributes) + ifcopenshell.api.profile.edit_profile(tool.Ifc.get(), profile=profile, attributes=attributes) self.props.active_material_set_item_id = 0 self.props.material_set_item_profile_attributes.clear() model_profile.DumbProfileRegenerator().regenerate_from_profile_def(profile) @@ -900,7 +896,7 @@ class EditMaterialStyle(bpy.types.Operator, tool.Ifc.Operator): material = ifc_file.by_id(props.active_material_id) style = ifc_file.by_id(int(props.styles)) context = ifc_file.by_id(int(props.contexts)) - ifcopenshell.api.run("style.assign_material_style", ifc_file, material=material, style=style, context=context) + ifcopenshell.api.style.assign_material_style(ifc_file, material=material, style=style, context=context) tool.Material.disable_editing_material() core.load_materials(tool.Material, props.material_type) # NOTE: Update all elements that has this material and @@ -923,9 +919,7 @@ class UnassignMaterialStyle(bpy.types.Operator, tool.Ifc.Operator): material = tool.Ifc.get().by_id(props.materials[props.active_material_index].ifc_definition_id) style = tool.Ifc.get().by_id(self.style) context = tool.Ifc.get().by_id(self.context) - ifcopenshell.api.run( - "style.unassign_material_style", tool.Ifc.get(), material=material, style=style, context=context - ) + ifcopenshell.api.style.unassign_material_style(tool.Ifc.get(), material=material, style=style, context=context) core.load_materials(tool.Material, props.material_type) tool.Material.update_elements_using_material(material) diff --git a/src/bonsai/bonsai/bim/module/model/array.py b/src/bonsai/bonsai/bim/module/model/array.py index 5bfbfbda59..ec1bce2096 100644 --- a/src/bonsai/bonsai/bim/module/model/array.py +++ b/src/bonsai/bonsai/bim/module/model/array.py @@ -164,7 +164,7 @@ class EditArray(bpy.types.Operator, tool.Ifc.Operator): pset = tool.Ifc.get().by_id(pset["id"]) data = tool.Ifc.get().createIfcText(json.dumps(data)) - ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties={"Data": data}) + ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties={"Data": data}) tool.Blender.Modifier.Array.set_children_lock_state(element, self.item, True) tool.Blender.Modifier.Array.constrain_children_to_parent(element) @@ -228,11 +228,11 @@ class RemoveArray(bpy.types.Operator, tool.Ifc.Operator): pset = tool.Ifc.get().by_id(pset["id"]) if len(data) == 1: - ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), product=element, pset=pset) + ifcopenshell.api.pset.remove_pset(tool.Ifc.get(), product=element, pset=pset) else: del data[self.item] data = tool.Ifc.get().createIfcText(json.dumps(data)) - ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties={"Data": data}) + ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties={"Data": data}) tool.Blender.Modifier.Array.constrain_children_to_parent(element) return {"FINISHED"} diff --git a/src/bonsai/bonsai/bim/module/model/door.py b/src/bonsai/bonsai/bim/module/model/door.py index 32800f5835..62a5dcf074 100644 --- a/src/bonsai/bonsai/bim/module/model/door.py +++ b/src/bonsai/bonsai/bim/module/model/door.py @@ -21,7 +21,9 @@ import bpy import bmesh import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.geometry import ifcopenshell.api.material +import ifcopenshell.api.pset import ifcopenshell.util.element import ifcopenshell.util.representation import ifcopenshell.util.schema @@ -37,6 +39,7 @@ from typing import Union, Any, Optional import json import collections +import collections.abc V_ = tool.Blender.V_ @@ -80,9 +83,7 @@ def update_door_modifier_representation(obj: bpy.types.Object) -> None: profile = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Profile", "ELEVATION_VIEW") if profile: representation_data["context"] = profile - elevation_representation = ifcopenshell.api.run( - "geometry.add_door_representation", ifc_file, **representation_data - ) + elevation_representation = ifcopenshell.api.geometry.add_door_representation(ifc_file, **representation_data) tool.Model.replace_object_ifc_representation(profile, obj, elevation_representation) # MODEL_VIEW representation @@ -90,7 +91,7 @@ def update_door_modifier_representation(obj: bpy.types.Object) -> None: body = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW") representation_data["context"] = body representation_data["part_of_product"] = ifcopenshell.util.representation.get_part_of_product(element, body) - model_representation = ifcopenshell.api.run("geometry.add_door_representation", ifc_file, **representation_data) + model_representation = ifcopenshell.api.geometry.add_door_representation(ifc_file, **representation_data) representation_data["part_of_product"] = None tool.Model.replace_object_ifc_representation(body, obj, model_representation) if fallback_material := (int(props.lining_material) or int(props.framing_material) or int(props.glazing_material)): @@ -113,7 +114,7 @@ def update_door_modifier_representation(obj: bpy.types.Object) -> None: plan_body = ifcopenshell.util.representation.get_context(ifc_file, "Plan", "Body", "PLAN_VIEW") if plan_body: representation_data["context"] = plan_body - plan_representation = ifcopenshell.api.run("geometry.add_door_representation", ifc_file, **representation_data) + plan_representation = ifcopenshell.api.geometry.add_door_representation(ifc_file, **representation_data) tool.Model.replace_object_ifc_representation(plan_body, obj, plan_representation) # Annotation/PLAN_VIEW representation @@ -134,9 +135,7 @@ def update_door_modifier_representation(obj: bpy.types.Object) -> None: ) else: representation_data["context"] = plan_annotation - plan_representation = ifcopenshell.api.run( - "geometry.add_door_representation", ifc_file, **representation_data - ) + plan_representation = ifcopenshell.api.geometry.add_door_representation(ifc_file, **representation_data) tool.Model.replace_object_ifc_representation(plan_annotation, obj, plan_representation) bonsai.core.geometry.switch_representation( @@ -539,10 +538,9 @@ class AddDoor(bpy.types.Operator, tool.Ifc.Operator): pset = tool.Pset.get_element_pset(element, "BBIM_Door") if not pset: - pset = ifcopenshell.api.run("pset.add_pset", tool.Ifc.get(), product=element, name="BBIM_Door") + pset = ifcopenshell.api.pset.add_pset(tool.Ifc.get(), product=element, name="BBIM_Door") - ifcopenshell.api.run( - "pset.edit_pset", + ifcopenshell.api.pset.edit_pset( tool.Ifc.get(), pset=pset, properties={"Data": tool.Ifc.get().createIfcText(json.dumps(door_data, default=list))}, @@ -622,7 +620,7 @@ class FinishEditingDoor(bpy.types.Operator, tool.Ifc.Operator): pset = tool.Pset.get_element_pset(element, "BBIM_Door") door_data = tool.Ifc.get().createIfcText(json.dumps(door_data, default=list)) - ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties={"Data": door_data}) + ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties={"Data": door_data}) def _execute(self, context): for obj in tool.Blender.get_selected_objects(): @@ -670,7 +668,7 @@ class RemoveDoor(bpy.types.Operator, tool.Ifc.Operator): props.is_editing = False pset = tool.Pset.get_element_pset(element, "BBIM_Door") - ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), product=element, pset=pset) + ifcopenshell.api.pset.remove_pset(tool.Ifc.get(), product=element, pset=pset) def _execute(self, context): for obj in tool.Blender.get_selected_objects(): diff --git a/src/bonsai/bonsai/bim/module/model/mep.py b/src/bonsai/bonsai/bim/module/model/mep.py index bbbf11a021..6c1e90750d 100644 --- a/src/bonsai/bonsai/bim/module/model/mep.py +++ b/src/bonsai/bonsai/bim/module/model/mep.py @@ -19,15 +19,20 @@ import bpy import math import collections +import collections.abc import bmesh import re import json import ifcopenshell import ifcopenshell.api -import ifcopenshell.util.unit -import ifcopenshell.util.system +import ifcopenshell.api.geometry +import ifcopenshell.api.material +import ifcopenshell.api.pset import ifcopenshell.util.element +import ifcopenshell.util.placement import ifcopenshell.util.representation +import ifcopenshell.util.system +import ifcopenshell.util.unit import numpy as np import bonsai.core.type import bonsai.core.root @@ -539,14 +544,10 @@ class MEPGenerator: ifc_representation_class=None, ) - rel = ifcopenshell.api.run( - "material.assign_material", ifc_file, products=[element], type="IfcMaterialProfileSet" - ) + rel = ifcopenshell.api.material.assign_material(ifc_file, products=[element], type="IfcMaterialProfileSet") profile_set = rel.RelatingMaterial - material_profile = ifcopenshell.api.run( - "material.add_profile", ifc_file, profile_set=profile_set, material=material - ) - ifcopenshell.api.run("material.assign_profile", ifc_file, material_profile=material_profile, profile=profile) + material_profile = ifcopenshell.api.material.add_profile(ifc_file, profile_set=profile_set, material=material) + ifcopenshell.api.material.assign_profile(ifc_file, material_profile=material_profile, profile=profile) return element def add_obstruction(self, segment, length, at_segment_start=False): @@ -800,7 +801,7 @@ class MEPAddTransition(bpy.types.Operator, tool.Ifc.Operator): f"Failed to add transition - transition length is larger the segments and the distance between them.\n" + f"Transition length: {full_transition_length:.2f}m, segments length: {entire_length:.2f}m", ) - ifcopenshell.api.run("geometry.remove_representation", ifc_file, representation=rep) + ifcopenshell.api.geometry.remove_representation(ifc_file, representation=rep) return {"CANCELLED"} # calculate bunch of points to for adjustments @@ -832,7 +833,7 @@ class MEPAddTransition(bpy.types.Operator, tool.Ifc.Operator): start_port_match = fitting_data["start_port_match"] if fitting_data else True if transition_type: # TODO: handle the case without creating a representation in the first place? - ifcopenshell.api.run("geometry.remove_representation", ifc_file, representation=rep) + ifcopenshell.api.geometry.remove_representation(ifc_file, representation=rep) else: # create new fitting type if nothing is compatible mesh = bpy.data.meshes.new("Transition") obj = bpy.data.objects.new("Transition", mesh) @@ -848,9 +849,8 @@ class MEPAddTransition(bpy.types.Operator, tool.Ifc.Operator): body = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW") # Will implicitly remove `mesh`. tool.Model.replace_object_ifc_representation(body, obj, rep) - pset = ifcopenshell.api.run("pset.add_pset", tool.Ifc.get(), product=transition_type, name="BBIM_Fitting") - ifcopenshell.api.run( - "pset.edit_pset", + pset = ifcopenshell.api.pset.add_pset(tool.Ifc.get(), product=transition_type, name="BBIM_Fitting") + ifcopenshell.api.pset.edit_pset( tool.Ifc.get(), pset=pset, properties={"Data": tool.Ifc.get().createIfcText(json.dumps(transition_data, default=list))}, @@ -1183,7 +1183,7 @@ class MEPAddBend(bpy.types.Operator, tool.Ifc.Operator): z_sign_type = -1 if bbim_data["flip_z_axis"] else 1 # TODO: handle the case without creating a representation in the first place? - ifcopenshell.api.run("geometry.remove_representation", ifc_file, representation=rep) + ifcopenshell.api.geometry.remove_representation(ifc_file, representation=rep) else: # create new fitting type if nothing is compatible mesh = bpy.data.meshes.new("Bend") obj = bpy.data.objects.new("Bend", mesh) @@ -1199,9 +1199,8 @@ class MEPAddBend(bpy.types.Operator, tool.Ifc.Operator): body = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW") # Will implicitly remove `mesh`. tool.Model.replace_object_ifc_representation(body, obj, rep) - pset = ifcopenshell.api.run("pset.add_pset", tool.Ifc.get(), product=bend_type, name="BBIM_Fitting") - ifcopenshell.api.run( - "pset.edit_pset", + pset = ifcopenshell.api.pset.add_pset(tool.Ifc.get(), product=bend_type, name="BBIM_Fitting") + ifcopenshell.api.pset.edit_pset( tool.Ifc.get(), pset=pset, properties={"Data": tool.Ifc.get().createIfcText(json.dumps(bend_data, default=list))}, diff --git a/src/bonsai/bonsai/bim/module/model/opening.py b/src/bonsai/bonsai/bim/module/model/opening.py index fb4e39ed81..54e2228248 100644 --- a/src/bonsai/bonsai/bim/module/model/opening.py +++ b/src/bonsai/bonsai/bim/module/model/opening.py @@ -27,6 +27,7 @@ import ifcopenshell import ifcopenshell.api import ifcopenshell.api.geometry import ifcopenshell.api.feature +import ifcopenshell.api.root import ifcopenshell.geom import ifcopenshell.util.shape import ifcopenshell.util.element @@ -68,8 +69,8 @@ class FilledOpeningGenerator: assert filling and element if filling.FillsVoids: - ifcopenshell.api.run( - "feature.remove_feature", tool.Ifc.get(), feature=filling.FillsVoids[0].RelatingOpeningElement + ifcopenshell.api.feature.remove_feature( + tool.Ifc.get(), feature=filling.FillsVoids[0].RelatingOpeningElement ) if target is None: @@ -123,15 +124,13 @@ class FilledOpeningGenerator: existing_opening_occurrence = self.get_existing_opening_occurrence_if_any(filling) - opening = ifcopenshell.api.run( - "root.create_entity", + opening = ifcopenshell.api.root.create_entity( tool.Ifc.get(), ifc_class="IfcOpeningElement", predefined_type="OPENING", name="Opening", ) - ifcopenshell.api.run( - "geometry.edit_object_placement", + ifcopenshell.api.geometry.edit_object_placement( tool.Ifc.get(), product=opening, matrix=np.array(filling_obj.matrix_world), @@ -149,15 +148,15 @@ class FilledOpeningGenerator: filling, filling_obj, opening_thickness_si=opening_thickness_si ) - mapped_representation = ifcopenshell.api.run( - "geometry.map_representation", tool.Ifc.get(), representation=representation + mapped_representation = ifcopenshell.api.geometry.map_representation( + tool.Ifc.get(), representation=representation ) - ifcopenshell.api.run( - "geometry.assign_representation", tool.Ifc.get(), product=opening, representation=mapped_representation + ifcopenshell.api.geometry.assign_representation( + tool.Ifc.get(), product=opening, representation=mapped_representation ) - ifcopenshell.api.run("feature.add_feature", tool.Ifc.get(), feature=opening, element=element) - ifcopenshell.api.run("feature.add_filling", tool.Ifc.get(), opening=opening, element=filling) + ifcopenshell.api.feature.add_feature(tool.Ifc.get(), feature=opening, element=element) + ifcopenshell.api.feature.add_filling(tool.Ifc.get(), opening=opening, element=filling) voided_objs = [voided_obj] # Openings affect all subelements of an aggregate @@ -199,10 +198,8 @@ class FilledOpeningGenerator: voided_element = opening.VoidsElements[0].RelatingBuildingElement opening_rep = ifcopenshell.util.representation.get_representation(opening, "Model", "Body", "MODEL_VIEW") - ifcopenshell.api.run( - "geometry.unassign_representation", tool.Ifc.get(), product=opening, representation=opening_rep - ) - ifcopenshell.api.run("geometry.remove_representation", tool.Ifc.get(), representation=opening_rep) + ifcopenshell.api.geometry.unassign_representation(tool.Ifc.get(), product=opening, representation=opening_rep) + ifcopenshell.api.geometry.remove_representation(tool.Ifc.get(), representation=opening_rep) existing_opening_occurrence = self.get_existing_opening_occurrence_if_any(filling) @@ -211,11 +208,11 @@ class FilledOpeningGenerator: existing_opening_occurrence, "Model", "Body", "MODEL_VIEW" ) representation = ifcopenshell.util.representation.resolve_representation(representation) - mapped_representation = ifcopenshell.api.run( - "geometry.map_representation", tool.Ifc.get(), representation=representation + mapped_representation = ifcopenshell.api.geometry.map_representation( + tool.Ifc.get(), representation=representation ) - ifcopenshell.api.run( - "geometry.assign_representation", tool.Ifc.get(), product=opening, representation=mapped_representation + ifcopenshell.api.geometry.assign_representation( + tool.Ifc.get(), product=opening, representation=mapped_representation ) else: opening_obj = tool.Ifc.get_object(opening) @@ -225,11 +222,11 @@ class FilledOpeningGenerator: filling_obj = tool.Ifc.get_object(filling) representation = self.generate_opening_from_filling(filling, filling_obj) - mapped_representation = ifcopenshell.api.run( - "geometry.map_representation", tool.Ifc.get(), representation=representation + mapped_representation = ifcopenshell.api.geometry.map_representation( + tool.Ifc.get(), representation=representation ) - ifcopenshell.api.run( - "geometry.assign_representation", tool.Ifc.get(), product=opening, representation=mapped_representation + ifcopenshell.api.geometry.assign_representation( + tool.Ifc.get(), product=opening, representation=mapped_representation ) # update voided object representation or all it's parts if it's an aggregate @@ -396,8 +393,8 @@ class RecalculateFill(bpy.types.Operator, tool.Ifc.Operator): bonsai.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=building_obj) for opening in openings: bonsai.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj) - ifcopenshell.api.run( - "geometry.edit_object_placement", tool.Ifc.get(), product=opening, matrix=obj.matrix_world + ifcopenshell.api.geometry.edit_object_placement( + tool.Ifc.get(), product=opening, matrix=obj.matrix_world ) decomposed_building_elements = set() @@ -737,7 +734,7 @@ class CloneOpening(Operator, tool.Ifc.Operator): opening_placement = opening.ObjectPlacement opening_representation = opening.Representation - new_opening = ifcopenshell.api.run("root.create_entity", tool.Ifc.get(), ifc_class="IfcOpeningElement") + new_opening = ifcopenshell.api.root.create_entity(tool.Ifc.get(), ifc_class="IfcOpeningElement") new_opening.Representation = opening_representation ifcopenshell.api.feature.add_feature(ifc_file, feature=new_opening, element=voided_element) diff --git a/src/bonsai/bonsai/bim/module/model/product.py b/src/bonsai/bonsai/bim/module/model/product.py index 3a1795396a..78e1f35cfb 100644 --- a/src/bonsai/bonsai/bim/module/model/product.py +++ b/src/bonsai/bonsai/bim/module/model/product.py @@ -687,11 +687,8 @@ def generate_box(usecase_path: str, ifc_file: ifcopenshell.file, settings: dict[ new_settings = settings.copy() new_settings["context"] = box_context - new_box = ifcopenshell.api.run( - "geometry.add_representation", ifc_file, should_run_listeners=False, **new_settings - ) - ifcopenshell.api.run( - "geometry.assign_representation", + new_box = ifcopenshell.api.geometry.add_representation(ifc_file, should_run_listeners=False, **new_settings) + ifcopenshell.api.geometry.assign_representation( ifc_file, should_run_listeners=False, **{"product": product, "representation": new_box}, diff --git a/src/bonsai/bonsai/bim/module/model/profile.py b/src/bonsai/bonsai/bim/module/model/profile.py index c28c9b0718..feec98764d 100644 --- a/src/bonsai/bonsai/bim/module/model/profile.py +++ b/src/bonsai/bonsai/bim/module/model/profile.py @@ -23,6 +23,8 @@ import mathutils.geometry import ifcopenshell import ifcopenshell.api import ifcopenshell.api.geometry +import ifcopenshell.api.pset +import ifcopenshell.api.type import ifcopenshell.util.type import ifcopenshell.util.unit import ifcopenshell.util.element @@ -125,7 +127,7 @@ class DumbProfileGenerator: ifc_class=ifc_class, should_add_representation=False, ) - ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=self.relating_type) + ifcopenshell.api.type.assign_type(self.file, related_objects=[element], relating_type=self.relating_type) material = ifcopenshell.util.element.get_material(element) material.CardinalPoint = self.cardinal_point @@ -135,27 +137,23 @@ class DumbProfileGenerator: bonsai.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj) if self.axis_context: - representation = ifcopenshell.api.run( - "geometry.add_axis_representation", + representation = ifcopenshell.api.geometry.add_axis_representation( tool.Ifc.get(), context=self.axis_context, axis=[(0.0, 0.0, 0.0), (0.0, 0.0, self.depth)], ) - ifcopenshell.api.run( - "geometry.assign_representation", tool.Ifc.get(), product=element, representation=representation + ifcopenshell.api.geometry.assign_representation( + tool.Ifc.get(), product=element, representation=representation ) - representation = ifcopenshell.api.run( - "geometry.add_profile_representation", + representation = ifcopenshell.api.geometry.add_profile_representation( tool.Ifc.get(), context=self.body_context, profile=self.profile_set.CompositeProfile or self.profile_set.MaterialProfiles[0].Profile, cardinal_point=self.cardinal_point, depth=self.depth, ) - ifcopenshell.api.run( - "geometry.assign_representation", tool.Ifc.get(), product=element, representation=representation - ) + ifcopenshell.api.geometry.assign_representation(tool.Ifc.get(), product=element, representation=representation) bonsai.core.geometry.switch_representation( tool.Ifc, tool.Geometry, @@ -166,8 +164,8 @@ class DumbProfileGenerator: should_sync_changes_first=False, ) - pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="EPset_Parametric") - ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Engine": "Bonsai.DumbProfile"}) + pset = ifcopenshell.api.pset.add_pset(self.file, product=element, name="EPset_Parametric") + ifcopenshell.api.pset.edit_pset(self.file, pset=pset, properties={"Engine": "Bonsai.DumbProfile"}) tool.Blender.select_object(obj) @@ -323,8 +321,8 @@ class DumbProfileJoiner: if not element1: return - ifcopenshell.api.run("geometry.disconnect_path", tool.Ifc.get(), element=element1, connection_type="ATSTART") - ifcopenshell.api.run("geometry.disconnect_path", tool.Ifc.get(), element=element1, connection_type="ATEND") + ifcopenshell.api.geometry.disconnect_path(tool.Ifc.get(), element=element1, connection_type="ATSTART") + ifcopenshell.api.geometry.disconnect_path(tool.Ifc.get(), element=element1, connection_type="ATEND") axis1 = self.get_profile_axis(profile1) axis = copy.deepcopy(axis1) @@ -347,7 +345,7 @@ class DumbProfileJoiner: if connection is None: connection = "ATEND" if connection_value > 0.5 else "ATSTART" - ifcopenshell.api.run("geometry.disconnect_path", tool.Ifc.get(), element=element1, connection_type=connection) + ifcopenshell.api.geometry.disconnect_path(tool.Ifc.get(), element=element1, connection_type=connection) axis = copy.deepcopy(axis1) body = copy.deepcopy(axis1) @@ -360,7 +358,7 @@ class DumbProfileJoiner: if not element1: return - ifcopenshell.api.run("geometry.disconnect_path", tool.Ifc.get(), element=element1, connection_type="ATEND") + ifcopenshell.api.geometry.disconnect_path(tool.Ifc.get(), element=element1, connection_type="ATEND") axis1 = self.get_profile_axis(profile1) axis = copy.deepcopy(axis1) @@ -382,8 +380,7 @@ class DumbProfileJoiner: return connection = "ATEND" if tool.Cad.edge_percent(intersect, axis1) > 0.5 else "ATSTART" - ifcopenshell.api.run( - "geometry.connect_path", + ifcopenshell.api.geometry.connect_path( tool.Ifc.get(), related_element=element1, relating_element=element2, @@ -407,8 +404,7 @@ class DumbProfileJoiner: profile1_end = "ATEND" if tool.Cad.edge_percent(intersect, axis1) > 0.5 else "ATSTART" profile2_end = "ATEND" if tool.Cad.edge_percent(intersect, axis2) > 0.5 else "ATSTART" - ifcopenshell.api.run( - "geometry.connect_path", + ifcopenshell.api.geometry.connect_path( tool.Ifc.get(), relating_element=element1, related_element=element2, @@ -433,8 +429,7 @@ class DumbProfileJoiner: profile1_end = "ATEND" if tool.Cad.edge_percent(intersect, axis1) > 0.5 else "ATSTART" profile2_end = "ATEND" if tool.Cad.edge_percent(intersect, axis2) > 0.5 else "ATSTART" - ifcopenshell.api.run( - "geometry.connect_path", + ifcopenshell.api.geometry.connect_path( tool.Ifc.get(), relating_element=element1, related_element=element2, @@ -492,8 +487,8 @@ class DumbProfileJoiner: if self.axis_context: axis = [(new_matrix @ a) for a in self.axis] - new_axis = ifcopenshell.api.run( - "geometry.add_axis_representation", tool.Ifc.get(), context=self.axis_context, axis=axis + new_axis = ifcopenshell.api.geometry.add_axis_representation( + tool.Ifc.get(), context=self.axis_context, axis=axis ) old_axis = ifcopenshell.util.representation.get_representation(element, "Model", "Axis", "GRAPH_VIEW") if old_axis: @@ -501,8 +496,8 @@ class DumbProfileJoiner: ifcopenshell.util.element.replace_attribute(inverse, old_axis, new_axis) bonsai.core.geometry.remove_representation(tool.Ifc, tool.Geometry, obj=obj, representation=old_axis) else: - ifcopenshell.api.run( - "geometry.assign_representation", tool.Ifc.get(), product=element, representation=new_axis + ifcopenshell.api.geometry.assign_representation( + tool.Ifc.get(), product=element, representation=new_axis ) def get_placement_axes( @@ -537,9 +532,7 @@ class DumbProfileJoiner: mesh.name = tool.Loader.get_mesh_name(new_body) bonsai.core.geometry.remove_representation(tool.Ifc, tool.Geometry, obj=obj, representation=old_body) else: - ifcopenshell.api.run( - "geometry.assign_representation", tool.Ifc.get(), product=element, representation=new_body - ) + ifcopenshell.api.geometry.assign_representation(tool.Ifc.get(), product=element, representation=new_body) previous_matrix = obj.matrix_world.copy() previous_origin = obj.location.copy() @@ -955,15 +948,9 @@ class Rotate90(bpy.types.Operator, tool.Ifc.Operator): elif usage == "LAYER2": layer2_objs.append(obj) if element.ConnectedTo or element.ConnectedFrom: - ifcopenshell.api.run( - "geometry.disconnect_path", tool.Ifc.get(), element=element, connection_type="ATSTART" - ) - ifcopenshell.api.run( - "geometry.disconnect_path", tool.Ifc.get(), element=element, connection_type="ATEND" - ) - ifcopenshell.api.run( - "geometry.disconnect_path", tool.Ifc.get(), element=element, connection_type="ATPATH" - ) + ifcopenshell.api.geometry.disconnect_path(tool.Ifc.get(), element=element, connection_type="ATSTART") + ifcopenshell.api.geometry.disconnect_path(tool.Ifc.get(), element=element, connection_type="ATEND") + ifcopenshell.api.geometry.disconnect_path(tool.Ifc.get(), element=element, connection_type="ATPATH") rotate_matrix = Matrix.Rotation(pi / 2, 4, self.axis) obj.matrix_world @= rotate_matrix bpy.context.view_layer.update() diff --git a/src/bonsai/bonsai/bim/module/model/railing.py b/src/bonsai/bonsai/bim/module/model/railing.py index ba8a5de7d0..28ac149325 100644 --- a/src/bonsai/bonsai/bim/module/model/railing.py +++ b/src/bonsai/bonsai/bim/module/model/railing.py @@ -21,6 +21,8 @@ import bpy import bmesh import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.geometry +import ifcopenshell.api.pset import ifcopenshell.util.representation import ifcopenshell.util.unit import bonsai.core.root @@ -71,10 +73,9 @@ def update_railing_modifier_ifc_data(context: bpy.types.Context) -> None: # update pset pset_common = tool.Pset.get_element_pset(element, "Pset_RailingCommon") if not pset_common: - pset_common = ifcopenshell.api.run("pset.add_pset", ifc_file, product=element, name="Pset_RailingCommon") + pset_common = ifcopenshell.api.pset.add_pset(ifc_file, product=element, name="Pset_RailingCommon") - ifcopenshell.api.run( - "pset.edit_pset", + ifcopenshell.api.pset.edit_pset( ifc_file, pset=pset_common, properties={ @@ -102,9 +103,7 @@ def update_railing_modifier_ifc_data(context: bpy.types.Context) -> None: "height": props.height / si_conversion, "looped_path": looped_path, } - model_representation = ifcopenshell.api.run( - "geometry.add_railing_representation", ifc_file, **representation_data - ) + model_representation = ifcopenshell.api.geometry.add_railing_representation(ifc_file, **representation_data) tool.Model.replace_object_ifc_representation(body, obj, model_representation) elif props.railing_type == "FRAMELESS_PANEL": @@ -114,9 +113,9 @@ def update_railing_modifier_ifc_data(context: bpy.types.Context) -> None: def update_bbim_railing_pset(element: ifcopenshell.entity_instance, railing_data: dict[str, Any]) -> None: pset = tool.Pset.get_element_pset(element, "BBIM_Railing") if not pset: - pset = ifcopenshell.api.run("pset.add_pset", tool.Ifc.get(), product=element, name="BBIM_Railing") + pset = ifcopenshell.api.pset.add_pset(tool.Ifc.get(), product=element, name="BBIM_Railing") railing_data = tool.Ifc.get().createIfcText(json.dumps(railing_data, default=list)) - ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties={"Data": railing_data}) + ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties={"Data": railing_data}) def update_railing_modifier_bmesh(context: bpy.types.Context) -> None: @@ -598,5 +597,5 @@ class RemoveRailing(bpy.types.Operator, tool.Ifc.Operator): props.is_editing = False pset = tool.Pset.get_element_pset(element, "BBIM_Railing") - ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), product=element, pset=pset) + ifcopenshell.api.pset.remove_pset(tool.Ifc.get(), product=element, pset=pset) return {"FINISHED"} diff --git a/src/bonsai/bonsai/bim/module/model/roof.py b/src/bonsai/bonsai/bim/module/model/roof.py index 1522844d0b..f67f58a591 100644 --- a/src/bonsai/bonsai/bim/module/model/roof.py +++ b/src/bonsai/bonsai/bim/module/model/roof.py @@ -21,6 +21,7 @@ import bmesh import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.pset import ifcopenshell.util.representation import ifcopenshell.util.unit import bonsai.core.root @@ -440,9 +441,9 @@ def update_roof_modifier_ifc_data(context: bpy.types.Context) -> None: def update_bbim_roof_pset(element: ifcopenshell.entity_instance, roof_data: dict[str, Any]) -> None: pset = tool.Pset.get_element_pset(element, "BBIM_Roof") if not pset: - pset = ifcopenshell.api.run("pset.add_pset", tool.Ifc.get(), product=element, name="BBIM_Roof") + pset = ifcopenshell.api.pset.add_pset(tool.Ifc.get(), product=element, name="BBIM_Roof") roof_data = tool.Ifc.get().createIfcText(json.dumps(roof_data, default=list)) - ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties={"Data": roof_data}) + ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties={"Data": roof_data}) def update_roof_modifier_bmesh(obj: bpy.types.Object) -> None: @@ -831,7 +832,7 @@ class RemoveRoof(bpy.types.Operator, tool.Ifc.Operator): assert element pset = tool.Pset.get_element_pset(element, "BBIM_Roof") - ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), product=element, pset=pset) + ifcopenshell.api.pset.remove_pset(tool.Ifc.get(), product=element, pset=pset) return {"FINISHED"} diff --git a/src/bonsai/bonsai/bim/module/model/slab.py b/src/bonsai/bonsai/bim/module/model/slab.py index 15a742aa5b..a93d4ea0a9 100644 --- a/src/bonsai/bonsai/bim/module/model/slab.py +++ b/src/bonsai/bonsai/bim/module/model/slab.py @@ -22,6 +22,9 @@ import bmesh import ifcopenshell import ifcopenshell.api import ifcopenshell.api.geometry +import ifcopenshell.api.material +import ifcopenshell.api.pset +import ifcopenshell.api.type import ifcopenshell.util.element import ifcopenshell.util.placement import ifcopenshell.util.representation @@ -146,20 +149,17 @@ class DumbSlabGenerator: ifc_class=ifc_class, should_add_representation=False, ) - ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=self.relating_type) + ifcopenshell.api.type.assign_type(self.file, related_objects=[element], relating_type=self.relating_type) bonsai.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj) - representation = ifcopenshell.api.run( - "geometry.add_slab_representation", + representation = ifcopenshell.api.geometry.add_slab_representation( tool.Ifc.get(), context=self.body_context, depth=self.depth, x_angle=self.x_angle, polyline=self.polyline, ) - ifcopenshell.api.run( - "geometry.assign_representation", tool.Ifc.get(), product=element, representation=representation - ) + ifcopenshell.api.geometry.assign_representation(tool.Ifc.get(), product=element, representation=representation) bonsai.core.geometry.switch_representation( tool.Ifc, @@ -178,18 +178,17 @@ class DumbSlabGenerator: curves = [extrusion.SweptArea.OuterCurve] if extrusion.SweptArea.is_a("IfcArbitraryProfileDefWithVoids"): curves.extend(extrusion.SweptArea.InnerCurves) - representation = ifcopenshell.api.run( - "geometry.add_footprint_representation", + representation = ifcopenshell.api.geometry.add_footprint_representation( tool.Ifc.get(), context=self.footprint_context, curves=curves, ) - ifcopenshell.api.run( - "geometry.assign_representation", tool.Ifc.get(), product=element, representation=representation + ifcopenshell.api.geometry.assign_representation( + tool.Ifc.get(), product=element, representation=representation ) - pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="EPset_Parametric") - ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Engine": "Bonsai.DumbLayer3"}) + pset = ifcopenshell.api.pset.add_pset(self.file, product=element, name="EPset_Parametric") + ifcopenshell.api.pset.edit_pset(self.file, pset=pset, properties={"Engine": "Bonsai.DumbLayer3"}) material = ifcopenshell.util.element.get_material(element) material.LayerSetDirection = "AXIS3" tool.Blender.select_object(obj) @@ -562,9 +561,8 @@ class EditSketchExtrusionProfile(bpy.types.Operator, tool.Ifc.Operator): if pset: pset = tool.Ifc.get().by_id(pset["id"]) else: - pset = ifcopenshell.api.run("pset.add_pset", tool.Ifc.get(), product=element, name="EPset_Parametric") - ifcopenshell.api.run( - "pset.edit_pset", + pset = ifcopenshell.api.pset.add_pset(tool.Ifc.get(), product=element, name="EPset_Parametric") + ifcopenshell.api.pset.edit_pset( tool.Ifc.get(), pset=pset, properties={"Engine": "CADSketcher", "Entities": json.dumps(context.scene["sketcher"].to_dict())}, @@ -783,8 +781,8 @@ class EditExtrusionProfile(bpy.types.Operator, tool.Ifc.Operator): curves = [profile.OuterCurve] if profile.is_a("IfcArbitraryProfileDefWithVoids"): curves.extend(profile.InnerCurves) - new_footprint = ifcopenshell.api.run( - "geometry.add_footprint_representation", tool.Ifc.get(), context=footprint_context, curves=curves + new_footprint = ifcopenshell.api.geometry.add_footprint_representation( + tool.Ifc.get(), context=footprint_context, curves=curves ) old_footprint = ifcopenshell.util.representation.get_representation(element, "Plan", "FootPrint", "SKETCH_VIEW") if old_footprint: @@ -792,8 +790,8 @@ class EditExtrusionProfile(bpy.types.Operator, tool.Ifc.Operator): ifcopenshell.util.element.replace_attribute(inverse, old_footprint, new_footprint) bonsai.core.geometry.remove_representation(tool.Ifc, tool.Geometry, obj=obj, representation=old_footprint) else: - ifcopenshell.api.run( - "geometry.assign_representation", tool.Ifc.get(), product=element, representation=new_footprint + ifcopenshell.api.geometry.assign_representation( + tool.Ifc.get(), product=element, representation=new_footprint ) @@ -924,8 +922,7 @@ class DrawPolylineSlab(bpy.types.Operator, PolylineOperator, tool.Ifc.Operator): if not getattr(material_set_usage, "ForLayerSet", False): return attributes = {"OffsetFromReferenceLine": offset, "DirectionSense": direction_sense} - ifcopenshell.api.run( - "material.edit_layer_usage", + ifcopenshell.api.material.edit_layer_usage( model, **{"usage": material_set_usage, "attributes": attributes}, ) diff --git a/src/bonsai/bonsai/bim/module/model/stair.py b/src/bonsai/bonsai/bim/module/model/stair.py index 8034857007..d2b5184c76 100644 --- a/src/bonsai/bonsai/bim/module/model/stair.py +++ b/src/bonsai/bonsai/bim/module/model/stair.py @@ -20,7 +20,7 @@ import bpy import json import bmesh import ifcopenshell -import ifcopenshell.api +import ifcopenshell.api.pset import ifcopenshell.util.element import ifcopenshell.util.representation import ifcopenshell.util.unit @@ -98,10 +98,9 @@ def update_ifc_stair_props(obj: bpy.types.Object) -> None: # update pset with ifc properties pset_common = tool.Pset.get_element_pset(element, "Pset_StairFlightCommon") if not pset_common: - pset_common = ifcopenshell.api.run("pset.add_pset", ifc_file, product=element, name="Pset_StairFlightCommon") + pset_common = ifcopenshell.api.pset.add_pset(ifc_file, product=element, name="Pset_StairFlightCommon") - ifcopenshell.api.run( - "pset.edit_pset", + ifcopenshell.api.pset.edit_pset( ifc_file, pset=pset_common, properties={ @@ -192,10 +191,9 @@ class AddStair(bpy.types.Operator, tool.Ifc.Operator): stair_data = props.get_props_kwargs(convert_to_project_units=True) pset = tool.Pset.get_element_pset(element, "BBIM_Stair") if not pset: - pset = ifcopenshell.api.run("pset.add_pset", ifc_file, product=element, name="BBIM_Stair") + pset = ifcopenshell.api.pset.add_pset(ifc_file, product=element, name="BBIM_Stair") - ifcopenshell.api.run( - "pset.edit_pset", + ifcopenshell.api.pset.edit_pset( ifc_file, pset=pset, properties={"Data": tool.Ifc.get().createIfcText(json.dumps(stair_data))}, @@ -250,7 +248,7 @@ class FinishEditingStair(bpy.types.Operator, tool.Ifc.Operator): pset = tool.Pset.get_element_pset(element, "BBIM_Stair") data = tool.Ifc.get().createIfcText(json.dumps(data)) - ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties={"Data": data}) + ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties={"Data": data}) # update IfcStairFlight properties update_ifc_stair_props(obj) @@ -288,6 +286,6 @@ class RemoveStair(bpy.types.Operator, tool.Ifc.Operator): props.is_editing = False pset = tool.Pset.get_element_pset(element, "BBIM_Stair") - ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), product=element, pset=pset) + ifcopenshell.api.pset.remove_pset(tool.Ifc.get(), product=element, pset=pset) return {"FINISHED"} diff --git a/src/bonsai/bonsai/bim/module/model/sverchok_modifier.py b/src/bonsai/bonsai/bim/module/model/sverchok_modifier.py index 315b16a98c..08eccd6705 100644 --- a/src/bonsai/bonsai/bim/module/model/sverchok_modifier.py +++ b/src/bonsai/bonsai/bim/module/model/sverchok_modifier.py @@ -20,6 +20,8 @@ import bpy import bmesh import ifcopenshell +import ifcopenshell.api.pset +import ifcopenshell.util.element import bonsai.tool as tool import json @@ -165,10 +167,9 @@ class UpdateDataFromSverchok(bpy.types.Operator, tool.Ifc.Operator): if pset: pset = tool.Ifc.get().by_id(pset["id"]) else: - pset = ifcopenshell.api.run("pset.add_pset", tool.Ifc.get(), product=element, name="BBIM_Sverchok") + pset = ifcopenshell.api.pset.add_pset(tool.Ifc.get(), product=element, name="BBIM_Sverchok") - ifcopenshell.api.run( - "pset.edit_pset", + ifcopenshell.api.pset.edit_pset( tool.Ifc.get(), pset=pset, properties={"Data": tool.Ifc.get().createIfcText(json.dumps(sverchok_data))}, diff --git a/src/bonsai/bonsai/bim/module/model/task.py b/src/bonsai/bonsai/bim/module/model/task.py index 050c408f34..78d93bf78d 100644 --- a/src/bonsai/bonsai/bim/module/model/task.py +++ b/src/bonsai/bonsai/bim/module/model/task.py @@ -18,6 +18,7 @@ import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.pset import ifcopenshell.util.date @@ -30,11 +31,10 @@ def calculate_quantities(usecase_path, ifc_file, settings): if not element.ScheduleDuration: return task = [e for e in ifc_file.get_inverse(element) if e.is_a("IfcTask")][0] - qto = ifcopenshell.api.run( - "pset.add_qto", ifc_file, should_run_listeners=False, product=task, name="Qto_TaskBaseQuantities" + qto = ifcopenshell.api.pset.add_qto( + ifc_file, should_run_listeners=False, product=task, name="Qto_TaskBaseQuantities" ) - ifcopenshell.api.run( - "pset.edit_qto", + ifcopenshell.api.pset.edit_qto( ifc_file, should_run_listeners=False, qto=qto, diff --git a/src/bonsai/bonsai/bim/module/model/wall.py b/src/bonsai/bonsai/bim/module/model/wall.py index b8ec453037..7c9c3cc4ae 100644 --- a/src/bonsai/bonsai/bim/module/model/wall.py +++ b/src/bonsai/bonsai/bim/module/model/wall.py @@ -24,6 +24,11 @@ import math import numpy as np import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.feature +import ifcopenshell.api.material +import ifcopenshell.api.pset +import ifcopenshell.api.root +import ifcopenshell.api.type import ifcopenshell.api.geometry import ifcopenshell.util.unit import ifcopenshell.util.element @@ -634,7 +639,7 @@ class DrawPolylineWall(bpy.types.Operator, PolylineOperator, tool.Ifc.Operator): material_set_usage = model.by_id(material.id()) # if material.is_a("IfcMaterialLayerSetUsage"): attributes = {"OffsetFromReferenceLine": offset, "DirectionSense": direction_sense} - ifcopenshell.api.run("material.edit_layer_usage", model, usage=material_set_usage, attributes=attributes) + ifcopenshell.api.material.edit_layer_usage(model, usage=material_set_usage, attributes=attributes) tool.Model.recalculate_walls([wall["obj"]]) if walls: @@ -989,20 +994,18 @@ class DumbWallGenerator: ifc_class=ifc_class, should_add_representation=False, ) - ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=self.relating_type) + ifcopenshell.api.type.assign_type(self.file, related_objects=[element], relating_type=self.relating_type) if self.axis_context: - representation = ifcopenshell.api.run( - "geometry.add_axis_representation", + representation = ifcopenshell.api.geometry.add_axis_representation( tool.Ifc.get(), context=self.axis_context, axis=[(0.0, 0.0), (self.length, 0.0)], ) - ifcopenshell.api.run( - "geometry.assign_representation", tool.Ifc.get(), product=element, representation=representation + ifcopenshell.api.geometry.assign_representation( + tool.Ifc.get(), product=element, representation=representation ) bonsai.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj) - representation = ifcopenshell.api.run( - "geometry.add_wall_representation", + representation = ifcopenshell.api.geometry.add_wall_representation( tool.Ifc.get(), context=self.body_context, thickness=self.layers["thickness"], @@ -1012,9 +1015,7 @@ class DumbWallGenerator: height=self.height, x_angle=self.x_angle, ) - ifcopenshell.api.run( - "geometry.assign_representation", tool.Ifc.get(), product=element, representation=representation - ) + ifcopenshell.api.geometry.assign_representation(tool.Ifc.get(), product=element, representation=representation) bonsai.core.geometry.switch_representation( tool.Ifc, tool.Geometry, @@ -1024,8 +1025,8 @@ class DumbWallGenerator: is_global=True, should_sync_changes_first=False, ) - pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="EPset_Parametric") - ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Engine": "Bonsai.DumbLayer2"}) + pset = ifcopenshell.api.pset.add_pset(self.file, product=element, name="EPset_Parametric") + ifcopenshell.api.pset.edit_pset(self.file, pset=pset, properties={"Engine": "Bonsai.DumbLayer2"}) material = ifcopenshell.util.element.get_material(element) material.LayerSetDirection = "AXIS2" tool.Blender.select_object(obj) @@ -1102,8 +1103,8 @@ class DumbWallJoiner: if not element1: return - ifcopenshell.api.run("geometry.disconnect_path", tool.Ifc.get(), element=element1, connection_type="ATSTART") - ifcopenshell.api.run("geometry.disconnect_path", tool.Ifc.get(), element=element1, connection_type="ATEND") + ifcopenshell.api.geometry.disconnect_path(tool.Ifc.get(), element=element1, connection_type="ATSTART") + ifcopenshell.api.geometry.disconnect_path(tool.Ifc.get(), element=element1, connection_type="ATEND") axis1 = tool.Model.get_wall_axis(wall1) axis = copy.deepcopy(axis1["reference"]) @@ -1142,8 +1143,7 @@ class DumbWallJoiner: description = conn.Description if relating_element: - ifcopenshell.api.run( - "geometry.connect_path", + ifcopenshell.api.geometry.connect_path( tool.Ifc.get(), relating_element=relating_element, related_element=element2, @@ -1164,7 +1164,7 @@ class DumbWallJoiner: _, opening_position = mathutils.geometry.intersect_point_line(opening_location.to_2d(), *axis1["reference"]) if opening_position > cut_percentage: # The opening should be removed from element1. - ifcopenshell.api.run("feature.remove_feature", tool.Ifc.get(), feature=opening) + ifcopenshell.api.feature.remove_feature(tool.Ifc.get(), feature=opening) # Now let's check element2. for opening in [ @@ -1176,7 +1176,7 @@ class DumbWallJoiner: _, opening_position = mathutils.geometry.intersect_point_line(opening_location.to_2d(), *axis1["reference"]) if opening_position < cut_percentage: # The opening should be removed from element2. - ifcopenshell.api.run("feature.remove_feature", tool.Ifc.get(), feature=opening) + ifcopenshell.api.feature.remove_feature(tool.Ifc.get(), feature=opening) # During the duplication process, filled voids are not copied. So we # only need to check fillings on the original element1. @@ -1202,7 +1202,7 @@ class DumbWallJoiner: rel.RelatedBuildingElement = element2 # Remove the old opening - ifcopenshell.api.run("feature.remove_feature", tool.Ifc.get(), feature=opening) + ifcopenshell.api.feature.remove_feature(tool.Ifc.get(), feature=opening) p1, p2 = ifcopenshell.util.representation.get_reference_line(element1) p3 = (wall1.matrix_world.inverted() @ intersect.to_3d()).to_2d() / unit_scale @@ -1308,15 +1308,13 @@ class DumbWallJoiner: for rel in element1.ConnectedFrom: if rel.is_a() == "IfcRelConnectsElements" and rel.Description == "TOP": - ifcopenshell.api.run( - "geometry.disconnect_element", + ifcopenshell.api.geometry.disconnect_element( tool.Ifc.get(), relating_element=rel.RelatingElement, related_element=element1, ) - ifcopenshell.api.run( - "geometry.connect_element", + ifcopenshell.api.geometry.connect_element( tool.Ifc.get(), relating_element=element2, related_element=element1, @@ -1347,7 +1345,7 @@ class DumbWallJoiner: if not connection: connection = "ATEND" if intersection_point > 0.5 else "ATSTART" - ifcopenshell.api.run("geometry.disconnect_path", tool.Ifc.get(), element=element1, connection_type=connection) + ifcopenshell.api.geometry.disconnect_path(tool.Ifc.get(), element=element1, connection_type=connection) if connection == "ATEND": self.set_axis(element1, p1, intersect) diff --git a/src/bonsai/bonsai/bim/module/model/window.py b/src/bonsai/bonsai/bim/module/model/window.py index 4cd3bac0c9..16063d82ab 100644 --- a/src/bonsai/bonsai/bim/module/model/window.py +++ b/src/bonsai/bonsai/bim/module/model/window.py @@ -23,6 +23,8 @@ import bmesh import collections import collections.abc import ifcopenshell +import ifcopenshell.api.geometry +import ifcopenshell.api.pset import bonsai.tool as tool import bonsai.core.root import bonsai.core.geometry @@ -82,9 +84,7 @@ def update_window_modifier_representation(context: bpy.types.Context) -> None: profile = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Profile", "ELEVATION_VIEW") if profile: representation_data["context"] = profile - elevation_representation = ifcopenshell.api.run( - "geometry.add_window_representation", ifc_file, **representation_data - ) + elevation_representation = ifcopenshell.api.geometry.add_window_representation(ifc_file, **representation_data) tool.Model.replace_object_ifc_representation(profile, obj, elevation_representation) # MODEL_VIEW representation @@ -92,7 +92,7 @@ def update_window_modifier_representation(context: bpy.types.Context) -> None: body = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW") representation_data["context"] = body representation_data["part_of_product"] = ifcopenshell.util.representation.get_part_of_product(element, body) - model_representation = ifcopenshell.api.run("geometry.add_window_representation", ifc_file, **representation_data) + model_representation = ifcopenshell.api.geometry.add_window_representation(ifc_file, **representation_data) representation_data["part_of_product"] = None tool.Model.replace_object_ifc_representation(body, obj, model_representation) if fallback_material := (int(props.lining_material) or int(props.framing_material) or int(props.glazing_material)): @@ -115,9 +115,7 @@ def update_window_modifier_representation(context: bpy.types.Context) -> None: plan = ifcopenshell.util.representation.get_context(ifc_file, "Plan", "Body", "PLAN_VIEW") if plan: representation_data["context"] = plan - plan_representation = ifcopenshell.api.run( - "geometry.add_window_representation", ifc_file, **representation_data - ) + plan_representation = ifcopenshell.api.geometry.add_window_representation(ifc_file, **representation_data) tool.Model.replace_object_ifc_representation(plan, obj, plan_representation) bonsai.core.geometry.switch_representation( @@ -464,10 +462,9 @@ class AddWindow(bpy.types.Operator, tool.Ifc.Operator): window_data["panel_properties"] = panel_props pset = tool.Pset.get_element_pset(element, "BBIM_Window") if not pset: - pset = ifcopenshell.api.run("pset.add_pset", tool.Ifc.get(), product=element, name="BBIM_Window") + pset = ifcopenshell.api.pset.add_pset(tool.Ifc.get(), product=element, name="BBIM_Window") - ifcopenshell.api.run( - "pset.edit_pset", + ifcopenshell.api.pset.edit_pset( tool.Ifc.get(), pset=pset, properties={"Data": tool.Ifc.get().createIfcText(json.dumps(window_data, default=list))}, @@ -535,7 +532,7 @@ class FinishEditingWindow(bpy.types.Operator, tool.Ifc.Operator): pset = tool.Pset.get_element_pset(element, "BBIM_Window") window_data = tool.Ifc.get().createIfcText(json.dumps(window_data, default=list)) - ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties={"Data": window_data}) + ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties={"Data": window_data}) return {"FINISHED"} @@ -576,6 +573,6 @@ class RemoveWindow(bpy.types.Operator, tool.Ifc.Operator): props.is_editing = False pset = tool.Pset.get_element_pset(element, "BBIM_Window") - ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), product=element, pset=pset) + ifcopenshell.api.pset.remove_pset(tool.Ifc.get(), product=element, pset=pset) return {"FINISHED"} diff --git a/src/bonsai/bonsai/bim/module/project/operator.py b/src/bonsai/bonsai/bim/module/project/operator.py index 137108b45e..b30e02b9ac 100644 --- a/src/bonsai/bonsai/bim/module/project/operator.py +++ b/src/bonsai/bonsai/bim/module/project/operator.py @@ -174,6 +174,7 @@ class SelectLibraryFile(bpy.types.Operator, IFCFileSelector, ImportHelper): def _execute(self, context): filepath = self.get_filepath() ifc_file = tool.Ifc.get() + library_file: ifcopenshell.file library_file = ifcopenshell.open(filepath) if library_file.schema_identifier != ifc_file.schema_identifier: self.report( @@ -2158,8 +2159,7 @@ class AppendInspectedLinkedElement(AppendLibraryElement): return {"CANCELLED"} element_to_append = linked_ifc_file.by_guid(guid) - element = ifcopenshell.api.run( - "project.append_asset", + element = ifcopenshell.api.project.append_asset( tool.Ifc.get(), library=linked_ifc_file, element=element_to_append, diff --git a/src/bonsai/bonsai/bim/module/pset/operator.py b/src/bonsai/bonsai/bim/module/pset/operator.py index e7a1301c6f..ebd3e8009e 100644 --- a/src/bonsai/bonsai/bim/module/pset/operator.py +++ b/src/bonsai/bonsai/bim/module/pset/operator.py @@ -76,8 +76,8 @@ class DisablePsetEditing(bpy.types.Operator, tool.Ifc.Operator): pset = tool.Ifc.get().by_id(props.active_pset_id) ifc_definition_id = tool.Blender.get_obj_ifc_definition_id(self.obj, self.obj_type, context) if tool.Pset.is_pset_empty(pset): - ifcopenshell.api.run( - "pset.remove_pset", tool.Ifc.get(), product=tool.Ifc.get().by_id(ifc_definition_id), pset=pset + ifcopenshell.api.pset.remove_pset( + tool.Ifc.get(), product=tool.Ifc.get().by_id(ifc_definition_id), pset=pset ) props.active_pset_id = 0 props.active_pset_name = "" @@ -104,10 +104,10 @@ class EditPset(bpy.types.Operator, tool.Ifc.Operator): if pset_id: pset = self.file.by_id(pset_id) elif props.active_pset_type == "PSET": - pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name=props.active_pset_name) + pset = ifcopenshell.api.pset.add_pset(self.file, product=element, name=props.active_pset_name) props.active_pset_id = pset.id() elif props.active_pset_type == "QTO": - pset = ifcopenshell.api.run("pset.add_qto", self.file, product=element, name=props.active_pset_name) + pset = ifcopenshell.api.pset.add_qto(self.file, product=element, name=props.active_pset_name) props.active_pset_id = pset.id() if self.properties: @@ -123,8 +123,7 @@ class EditPset(bpy.types.Operator, tool.Ifc.Operator): ] if pset.is_a() in ("IfcPropertySet", "IfcMaterialProperties", "IfcProfileProperties"): - ifcopenshell.api.run( - "pset.edit_pset", + ifcopenshell.api.pset.edit_pset( self.file, pset=pset, name=props.active_pset_name, @@ -139,8 +138,7 @@ class EditPset(bpy.types.Operator, tool.Ifc.Operator): properties[key] = round(value, 4) elif not isinstance(value, int): properties[key] = 0 - ifcopenshell.api.run( - "pset.edit_qto", + ifcopenshell.api.pset.edit_qto( self.file, qto=pset, name=props.active_pset_name, @@ -175,8 +173,8 @@ class RemovePset(bpy.types.Operator, tool.Ifc.Operator): element = tool.Ifc.get().by_id(ifc_definition_id) pset = ifcopenshell.util.element.get_psets(element, should_inherit=False).get(pset_name, None) if pset: - ifcopenshell.api.run( - "pset.remove_pset", tool.Ifc.get(), product=element, pset=tool.Ifc.get().by_id(pset["id"]) + ifcopenshell.api.pset.remove_pset( + tool.Ifc.get(), product=element, pset=tool.Ifc.get().by_id(pset["id"]) ) @@ -364,9 +362,9 @@ class BIM_OT_add_edit_custom_property(bpy.types.Operator, tool.Ifc.Operator): elif prop.template_type == "IfcPropertySingleValue": value_ifc_entity = getattr(self.file, f"create{primary_measure_type}")(value) - new_pset = ifcopenshell.api.run("pset.add_pset", self.file, product=ifc_element, name=prop.pset_name) - ifcopenshell.api.run( - "pset.edit_pset", self.file, pset=new_pset, properties={prop.property_name: value_ifc_entity} + new_pset = ifcopenshell.api.pset.add_pset(self.file, product=ifc_element, name=prop.pset_name) + ifcopenshell.api.pset.edit_pset( + self.file, pset=new_pset, properties={prop.property_name: value_ifc_entity} ) self.report({"INFO"}, "Finished applying changes") return {"FINISHED"} diff --git a/src/bonsai/bonsai/bim/module/pset_template/operator.py b/src/bonsai/bonsai/bim/module/pset_template/operator.py index 49f54e2aec..56d363b30c 100644 --- a/src/bonsai/bonsai/bim/module/pset_template/operator.py +++ b/src/bonsai/bonsai/bim/module/pset_template/operator.py @@ -44,8 +44,8 @@ class AddPsetTemplateFile(bpy.types.Operator): template = ifcopenshell.file() filepath = (tool.Blender.get_data_dir_path("pset") / self.new_template_filename).with_suffix(".ifc").__str__() - pset_template = ifcopenshell.api.run("pset_template.add_pset_template", template) - ifcopenshell.api.run("pset_template.add_prop_template", template, pset_template=pset_template) + pset_template = ifcopenshell.api.pset_template.add_pset_template(template) + ifcopenshell.api.pset_template.add_prop_template(template, pset_template=pset_template) template.write(filepath) bonsai.bim.handler.refresh_ui_data() bonsai.bim.schema.reload(tool.Ifc.get().schema) @@ -82,8 +82,7 @@ class RemovePsetTemplate(bpy.types.Operator, tool.PsetTemplate.PsetTemplateOpera current_pset_template_id = int(props.pset_templates) if props.active_pset_template_id == current_pset_template_id: bpy.ops.bim.disable_editing_pset_template() - ifcopenshell.api.run( - "pset_template.remove_pset_template", + ifcopenshell.api.pset_template.remove_pset_template( self.template_file, **{"pset_template": self.template_file.by_id(current_pset_template_id)}, ) @@ -169,8 +168,7 @@ class EditPsetTemplate(bpy.types.Operator, tool.PsetTemplate.PsetTemplateOperato def _execute(self, context): props = tool.PsetTemplate.get_pset_template_props() - ifcopenshell.api.run( - "pset_template.edit_pset_template", + ifcopenshell.api.pset_template.edit_pset_template( IfcStore.pset_template_file, **{ "pset_template": IfcStore.pset_template_file.by_id(props.active_pset_template_id), @@ -232,8 +230,7 @@ class AddPropTemplate(bpy.types.Operator, tool.PsetTemplate.PsetTemplateOperator def _execute(self, context): props = tool.PsetTemplate.get_pset_template_props() pset_template_id = props.active_pset_template_id or int(props.pset_templates) - prop_template = ifcopenshell.api.run( - "pset_template.add_prop_template", + prop_template = ifcopenshell.api.pset_template.add_prop_template( IfcStore.pset_template_file, pset_template=IfcStore.pset_template_file.by_id(pset_template_id), ) @@ -251,8 +248,7 @@ class RemovePropTemplate(bpy.types.Operator, tool.PsetTemplate.PsetTemplateOpera prop_template: bpy.props.IntProperty() def _execute(self, context): - ifcopenshell.api.run( - "pset_template.remove_prop_template", + ifcopenshell.api.pset_template.remove_prop_template( IfcStore.pset_template_file, **{"prop_template": IfcStore.pset_template_file.by_id(self.prop_template)}, ) @@ -283,8 +279,7 @@ class EditPropTemplate(bpy.types.Operator, tool.PsetTemplate.PsetTemplateOperato if primary_measure_type == "-" or template_type.startswith("Q_"): primary_measure_type = None - ifcopenshell.api.run( - "pset_template.edit_prop_template", + ifcopenshell.api.pset_template.edit_prop_template( IfcStore.pset_template_file, prop_template=IfcStore.pset_template_file.by_id(props.active_prop_template_id), attributes={ diff --git a/src/bonsai/bonsai/bim/module/root/operator.py b/src/bonsai/bonsai/bim/module/root/operator.py index 9a490b5589..f5eca09500 100644 --- a/src/bonsai/bonsai/bim/module/root/operator.py +++ b/src/bonsai/bonsai/bim/module/root/operator.py @@ -21,6 +21,8 @@ import bmesh import ifcopenshell import ifcopenshell.api import ifcopenshell.api.geometry +import ifcopenshell.api.material +import ifcopenshell.api.pset import ifcopenshell.api.root import ifcopenshell.util.schema import ifcopenshell.util.element @@ -599,27 +601,27 @@ class AddElement(bpy.types.Operator, tool.Ifc.Operator): if materials: material = materials[0] # Arbitrarily pick a material else: - material = ifcopenshell.api.run("material.add_material", tool.Ifc.get(), name="Unknown") - rel = ifcopenshell.api.run( - "material.assign_material", tool.Ifc.get(), products=[element], type="IfcMaterialLayerSet" + material = ifcopenshell.api.material.add_material(tool.Ifc.get(), name="Unknown") + rel = ifcopenshell.api.material.assign_material( + tool.Ifc.get(), products=[element], type="IfcMaterialLayerSet" ) layer_set = rel.RelatingMaterial - layer = ifcopenshell.api.run("material.add_layer", tool.Ifc.get(), layer_set=layer_set, material=material) + layer = ifcopenshell.api.material.add_layer(tool.Ifc.get(), layer_set=layer_set, material=material) thickness = 0.1 # Arbitrary metric thickness for now layer.LayerThickness = thickness / unit_scale - pset = ifcopenshell.api.run("pset.add_pset", tool.Ifc.get(), product=element, name="EPset_Parametric") + pset = ifcopenshell.api.pset.add_pset(tool.Ifc.get(), product=element, name="EPset_Parametric") if representation_template == "LAYERSET_AXIS2": axis = "AXIS2" elif representation_template == "LAYERSET_AXIS3": axis = "AXIS3" - ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties={"LayerSetDirection": axis}) + ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties={"LayerSetDirection": axis}) elif representation_template == "PROFILESET" or representation_template.startswith("FLOW_SEGMENT_"): unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) materials = tool.Ifc.get().by_type("IfcMaterial") if materials: material = materials[0] # Arbitrarily pick a material else: - material = ifcopenshell.api.run("material.add_material", tool.Ifc.get(), name="Unknown") + material = ifcopenshell.api.material.add_material(tool.Ifc.get(), name="Unknown") if representation_template == "PROFILESET": profile_id = tool.Blender.get_enum_safe(props, "profile") if profile_id in ("-", None): @@ -670,16 +672,14 @@ class AddElement(bpy.types.Operator, tool.Ifc.Operator): WallThickness=default_thickness, ) - rel = ifcopenshell.api.run( - "material.assign_material", tool.Ifc.get(), products=[element], type="IfcMaterialProfileSet" + rel = ifcopenshell.api.material.assign_material( + tool.Ifc.get(), products=[element], type="IfcMaterialProfileSet" ) profile_set = rel.RelatingMaterial - material_profile = ifcopenshell.api.run( - "material.add_profile", tool.Ifc.get(), profile_set=profile_set, material=material - ) - ifcopenshell.api.run( - "material.assign_profile", tool.Ifc.get(), material_profile=material_profile, profile=profile + material_profile = ifcopenshell.api.material.add_profile( + tool.Ifc.get(), profile_set=profile_set, material=material ) + ifcopenshell.api.material.assign_profile(tool.Ifc.get(), material_profile=material_profile, profile=profile) elif representation_template == "WINDOW": with context.temp_override(active_object=obj, selected_objects=[]): bpy.ops.bim.add_window() diff --git a/src/bonsai/bonsai/bim/module/search/operator.py b/src/bonsai/bonsai/bim/module/search/operator.py index 9956f1270d..3503a149d6 100644 --- a/src/bonsai/bonsai/bim/module/search/operator.py +++ b/src/bonsai/bonsai/bim/module/search/operator.py @@ -21,7 +21,7 @@ import json import bisect import ifcopenshell import ifcopenshell.api -import ifcopenshell.guid +import ifcopenshell.api.group import ifcopenshell.util.element import ifcopenshell.util.selector import bonsai.tool as tool @@ -201,9 +201,9 @@ class SaveSearch(Operator, tool.Ifc.Operator): group = group[0] group.Description = description else: - group = ifcopenshell.api.run("group.add_group", tool.Ifc.get(), name=self.name, description=description) + group = ifcopenshell.api.group.add_group(tool.Ifc.get(), name=self.name, description=description) if results: - ifcopenshell.api.run("group.assign_group", tool.Ifc.get(), products=list(results), group=group) + ifcopenshell.api.group.assign_group(tool.Ifc.get(), products=list(results), group=group) def draw(self, context): row = self.layout.row() @@ -447,7 +447,7 @@ class SaveColourscheme(Operator, tool.Ifc.Operator): group.Description = json.dumps(description) else: description = json.dumps({"type": "BBIM_Search", "colourscheme": colourscheme, "colourscheme_query": query}) - group = ifcopenshell.api.run("group.add_group", tool.Ifc.get(), name=self.name, description=description) + group = ifcopenshell.api.group.add_group(tool.Ifc.get(), name=self.name, description=description) def invoke(self, context, event): return context.window_manager.invoke_props_dialog(self) diff --git a/src/bonsai/bonsai/bim/module/structural/operator.py b/src/bonsai/bonsai/bim/module/structural/operator.py index 6836633d54..88e953b02e 100644 --- a/src/bonsai/bonsai/bim/module/structural/operator.py +++ b/src/bonsai/bonsai/bim/module/structural/operator.py @@ -20,6 +20,7 @@ import bpy import json import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.aggregate import ifcopenshell.api.group import ifcopenshell.api.structural import ifcopenshell.util.attribute @@ -136,7 +137,7 @@ class RemoveStructuralConnectionCondition(bpy.types.Operator, tool.Ifc.Operator) file = tool.Ifc.get() relation = file.by_id(self.connects_structural_member) connection = relation.RelatedStructuralConnection - ifcopenshell.api.run("structural.remove_structural_connection_condition", file, **{"relation": relation}) + ifcopenshell.api.structural.remove_structural_connection_condition(file, **{"relation": relation}) return {"FINISHED"} @@ -149,7 +150,7 @@ class AddStructuralBoundaryCondition(bpy.types.Operator, tool.Ifc.Operator): def _execute(self, context): file = tool.Ifc.get() connection = file.by_id(self.connection) - ifcopenshell.api.run("structural.add_structural_boundary_condition", file, **{"connection": connection}) + ifcopenshell.api.structural.add_structural_boundary_condition(file, **{"connection": connection}) return {"FINISHED"} @@ -162,7 +163,7 @@ class RemoveStructuralBoundaryCondition(bpy.types.Operator, tool.Ifc.Operator): def _execute(self, context): file = tool.Ifc.get() connection = file.by_id(self.connection) - ifcopenshell.api.run("structural.remove_structural_boundary_condition", file, **{"connection": connection}) + ifcopenshell.api.structural.remove_structural_boundary_condition(file, **{"connection": connection}) return {"FINISHED"} @@ -233,8 +234,8 @@ class EditStructuralBoundaryCondition(bpy.types.Operator, tool.Ifc.Operator): else: attributes[attribute.name] = {"value": attribute.float_value, "type": attribute.enum_value} - ifcopenshell.api.run( - "structural.edit_structural_boundary_condition", file, **{"condition": condition, "attributes": attributes} + ifcopenshell.api.structural.edit_structural_boundary_condition( + file, **{"condition": condition, "attributes": attributes} ) bpy.ops.bim.disable_editing_structural_boundary_condition() return {"FINISHED"} @@ -425,8 +426,7 @@ class EditStructuralItemAxis(bpy.types.Operator, tool.Ifc.Operator): relative_matrix = props.axis_empty.matrix_world @ obj.matrix_world.inverted() z_axis = relative_matrix.col[2][0:3] self.file = tool.Ifc.get() - ifcopenshell.api.run( - "structural.edit_structural_item_axis", + ifcopenshell.api.structural.edit_structural_item_axis( self.file, structural_item=self.file.by_id(oprops.ifc_definition_id), axis=z_axis, @@ -536,8 +536,7 @@ class AssignStructuralLoadCase(bpy.types.Operator, tool.Ifc.Operator): def _execute(self, context): self.file = tool.Ifc.get() - ifcopenshell.api.run( - "aggregate.assign_object", + ifcopenshell.api.aggregate.assign_object( self.file, **{ "relating_object": self.file.by_id(self.work_plan), @@ -555,8 +554,7 @@ class UnassignStructuralLoadCase(bpy.types.Operator, tool.Ifc.Operator): def _execute(self, context): self.file = tool.Ifc.get() - ifcopenshell.api.run( - "aggregate.unassign_object", + ifcopenshell.api.aggregate.unassign_object( self.file, **{ "relating_object": self.file.by_id(self.work_plan), @@ -572,7 +570,7 @@ class AddStructuralLoadCase(bpy.types.Operator, tool.Ifc.Operator): bl_options = {"REGISTER", "UNDO"} def _execute(self, context): - ifcopenshell.api.run("structural.add_structural_load_case", tool.Ifc.get()) + ifcopenshell.api.structural.add_structural_load_case(tool.Ifc.get()) return {"FINISHED"} @@ -799,8 +797,8 @@ class AddStructuralLoad(bpy.types.Operator, tool.Ifc.Operator): ifc_class: bpy.props.StringProperty() def _execute(self, context): - result = ifcopenshell.api.run( - "structural.add_structural_load", tool.Ifc.get(), name="New Load", ifc_class=self.ifc_class + result = ifcopenshell.api.structural.add_structural_load( + tool.Ifc.get(), name="New Load", ifc_class=self.ifc_class ) bpy.ops.bim.load_structural_loads() bpy.ops.bim.enable_editing_structural_load(structural_load=result.id()) diff --git a/src/bonsai/bonsai/bim/module/style/operator.py b/src/bonsai/bonsai/bim/module/style/operator.py index 1a4f9b1f8f..a5a4a16e9b 100644 --- a/src/bonsai/bonsai/bim/module/style/operator.py +++ b/src/bonsai/bonsai/bim/module/style/operator.py @@ -812,16 +812,14 @@ class EditSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator): assert self.surface_style if self.surface_style.is_a() == "IfcSurfaceStyleShading": - ifcopenshell.api.run( - "style.edit_surface_style", + ifcopenshell.api.style.edit_surface_style( tool.Ifc.get(), style=self.surface_style, attributes=self.get_shading_attributes(), ) tool.Loader.create_surface_style_shading(material, self.surface_style) elif self.surface_style.is_a() == "IfcSurfaceStyleRendering": - ifcopenshell.api.run( - "style.edit_surface_style", + ifcopenshell.api.style.edit_surface_style( tool.Ifc.get(), style=self.surface_style, attributes=self.get_rendering_attributes(), @@ -858,8 +856,7 @@ class EditSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator): else: attributes = tool.Style.get_style_ui_props_attributes(self.surface_style.is_a()) assert attributes - ifcopenshell.api.run( - "style.edit_surface_style", + ifcopenshell.api.style.edit_surface_style( tool.Ifc.get(), style=self.surface_style, attributes=bonsai.bim.helper.export_attributes(attributes), @@ -868,8 +865,7 @@ class EditSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator): def add_new_style(self) -> None: material = tool.Ifc.get_object(self.style) if self.props.is_editing_class == "IfcSurfaceStyleShading": - surface_style = ifcopenshell.api.run( - "style.add_surface_style", + surface_style = ifcopenshell.api.style.add_surface_style( tool.Ifc.get(), style=self.style, ifc_class="IfcSurfaceStyleShading", @@ -877,8 +873,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.run( - "style.add_surface_style", + surface_style = ifcopenshell.api.style.add_surface_style( tool.Ifc.get(), style=self.style, ifc_class="IfcSurfaceStyleRendering", @@ -901,8 +896,7 @@ class EditSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator): tool.Loader.create_surface_style_with_textures(material, self.rendering_style, texture_style) else: attributes = tool.Style.get_style_ui_props_attributes(self.props.is_editing_class) - surface_style = ifcopenshell.api.run( - "style.add_surface_style", + surface_style = ifcopenshell.api.style.add_surface_style( tool.Ifc.get(), style=self.style, ifc_class=self.props.is_editing_class, diff --git a/src/bonsai/bonsai/bim/module/system/operator.py b/src/bonsai/bonsai/bim/module/system/operator.py index b85ec4a666..517b4b48dd 100644 --- a/src/bonsai/bonsai/bim/module/system/operator.py +++ b/src/bonsai/bonsai/bim/module/system/operator.py @@ -18,6 +18,7 @@ import bpy import ifcopenshell.api +import ifcopenshell.api.system import ifcopenshell.util.system import bonsai.tool as tool import bonsai.core.system as core @@ -406,7 +407,7 @@ class AddZone(bpy.types.Operator, tool.Ifc.Operator): row.prop(self, "name", text="Name") def _execute(self, context): - element = ifcopenshell.api.run("system.add_system", tool.Ifc.get(), ifc_class="IfcZone") + element = ifcopenshell.api.system.add_system(tool.Ifc.get(), ifc_class="IfcZone") if self.name: element.Name = self.name bpy.ops.bim.load_zones() @@ -446,7 +447,7 @@ class EditZone(bpy.types.Operator, tool.Ifc.Operator): props = tool.System.get_zone_props() zone = tool.Ifc.get().by_id(props.is_editing) attributes = bonsai.bim.helper.export_attributes(props.attributes) - ifcopenshell.api.run("system.edit_system", tool.Ifc.get(), system=zone, attributes=attributes) + ifcopenshell.api.system.edit_system(tool.Ifc.get(), system=zone, attributes=attributes) props.is_editing = 0 bpy.ops.bim.load_zones() @@ -458,7 +459,7 @@ class RemoveZone(bpy.types.Operator, tool.Ifc.Operator): zone: bpy.props.IntProperty() def _execute(self, context): - ifcopenshell.api.run("system.remove_system", tool.Ifc.get(), system=tool.Ifc.get().by_id(self.zone)) + ifcopenshell.api.system.remove_system(tool.Ifc.get(), system=tool.Ifc.get().by_id(self.zone)) bpy.ops.bim.load_zones() diff --git a/src/bonsai/bonsai/bim/module/void/operator.py b/src/bonsai/bonsai/bim/module/void/operator.py index dfa82de6a7..737de84eeb 100644 --- a/src/bonsai/bonsai/bim/module/void/operator.py +++ b/src/bonsai/bonsai/bim/module/void/operator.py @@ -18,6 +18,7 @@ import bpy import ifcopenshell.api +import ifcopenshell.api.feature import ifcopenshell.util.element import ifcopenshell.util.representation import bonsai.tool as tool @@ -110,7 +111,7 @@ class AddOpening(bpy.types.Operator, tool.Ifc.Operator): should_add_representation=True, context=body_context, ) - ifcopenshell.api.run("feature.add_feature", tool.Ifc.get(), feature=element2, element=element1) + ifcopenshell.api.feature.add_feature(tool.Ifc.get(), feature=element2, element=element1) if tool.Ifc.is_moved(obj2): bonsai.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj2) @@ -180,7 +181,7 @@ class RemoveOpening(bpy.types.Operator, tool.Ifc.Operator): opening_obj.name = "/".join(opening_obj.name.split("/")[1:]) tool.Ifc.unlink(element=opening) - ifcopenshell.api.run("feature.remove_feature", tool.Ifc.get(), feature=opening) + ifcopenshell.api.feature.remove_feature(tool.Ifc.get(), feature=opening) decomposed_building_elements = {element} decomposed_building_elements.update(tool.Aggregate.get_parts_recursively(element)) @@ -221,8 +222,8 @@ class AddFilling(bpy.types.Operator, tool.Ifc.Operator): opening_id = tool.Blender.get_object_bim_props(opening).ifc_definition_id if not element_id or not opening_id or element_id == opening_id: return {"FINISHED"} - ifcopenshell.api.run( - "feature.add_filling", self.file, opening=self.file.by_id(opening_id), element=self.file.by_id(element_id) + ifcopenshell.api.feature.add_filling( + self.file, opening=self.file.by_id(opening_id), element=self.file.by_id(element_id) ) return {"FINISHED"} @@ -237,7 +238,7 @@ class RemoveFilling(bpy.types.Operator, tool.Ifc.Operator): filling = tool.Ifc.get().by_id(self.filling) for rel in filling.FillsVoids: bpy.ops.bim.remove_opening(opening_id=rel.RelatingOpeningElement.id()) - ifcopenshell.api.run("feature.remove_filling", tool.Ifc.get(), element=filling) + ifcopenshell.api.feature.remove_filling(tool.Ifc.get(), element=filling) return {"FINISHED"} diff --git a/src/bonsai/bonsai/bim/operator.py b/src/bonsai/bonsai/bim/operator.py index fc17184faf..889a1cffd6 100644 --- a/src/bonsai/bonsai/bim/operator.py +++ b/src/bonsai/bonsai/bim/operator.py @@ -823,6 +823,7 @@ class ReloadIfcFile(bpy.types.Operator, tool.Ifc.Operator, ImportHelper): import ifcdiff old = tool.Ifc.get() + new: ifcopenshell.file new = ifcopenshell.open(self.filepath) ifc_diff = ifcdiff.IfcDiff(old, new, relationships=[]) diff --git a/src/bonsai/bonsai/tool/cost.py b/src/bonsai/bonsai/tool/cost.py index d947b07349..4881456577 100644 --- a/src/bonsai/bonsai/tool/cost.py +++ b/src/bonsai/bonsai/tool/cost.py @@ -21,6 +21,8 @@ import bpy import bonsai.core.tool import bonsai.tool as tool import ifcopenshell.api +import ifcopenshell.api.cost +import ifcopenshell.api.nest import ifcopenshell.util.element import ifcopenshell.util.date import ifcopenshell.util.cost @@ -627,7 +629,7 @@ class Cost(bonsai.core.tool.Cost): items = ifcopenshell.util.cost.get_root_cost_items(cost_schedule) for item in items: cost_item_id = item.id() - ifcopenshell.api.run("cost.remove_cost_item", tool.Ifc.get(), cost_item=item) + ifcopenshell.api.cost.remove_cost_item(tool.Ifc.get(), cost_item=item) tool.Cost.clean_up_cost_item_tree(cost_item_id) @classmethod @@ -901,7 +903,7 @@ class Cost(bonsai.core.tool.Cost): def change_parent_cost_item( cls, cost_item: ifcopenshell.entity_instance, new_parent: ifcopenshell.entity_instance ) -> None: - ifcopenshell.api.run("nest.change_nest", tool.Ifc.get(), item=cost_item, new_parent=new_parent) + ifcopenshell.api.nest.change_nest(tool.Ifc.get(), item=cost_item, new_parent=new_parent) @classmethod def disable_editing_cost_item_parent(cls) -> None: diff --git a/src/bonsai/bonsai/tool/drawing.py b/src/bonsai/bonsai/tool/drawing.py index 021a474c2a..a8d4c90382 100644 --- a/src/bonsai/bonsai/tool/drawing.py +++ b/src/bonsai/bonsai/tool/drawing.py @@ -38,7 +38,10 @@ import bonsai.core.geometry import bonsai.core.type import bonsai.tool as tool import ifcopenshell.api +import ifcopenshell.api.context import ifcopenshell.api.document +import ifcopenshell.api.pset +import ifcopenshell.api.root import ifcopenshell.geom import ifcopenshell.util.representation import ifcopenshell.util.element @@ -376,7 +379,7 @@ class Drawing(bonsai.core.tool.Drawing): def delete_drawing_elements(cls, elements: Iterable[ifcopenshell.entity_instance]) -> None: for element in elements: obj = tool.Ifc.get_object(element) - ifcopenshell.api.run("root.remove_product", tool.Ifc.get(), product=element) + ifcopenshell.api.root.remove_product(tool.Ifc.get(), product=element) if obj: obj_data = obj.data bpy.data.objects.remove(obj) @@ -1187,9 +1190,8 @@ class Drawing(bonsai.core.tool.Drawing): ifc_file = tool.Ifc.get() pset = tool.Pset.get_element_pset(element, "EPset_Annotation") if not pset: - pset = ifcopenshell.api.run("pset.add_pset", ifc_file, product=element, name="EPset_Annotation") - ifcopenshell.api.run( - "pset.edit_pset", + pset = ifcopenshell.api.pset.add_pset(ifc_file, product=element, name="EPset_Annotation") + ifcopenshell.api.pset.edit_pset( ifc_file, pset=pset, properties={"Classes": classes}, @@ -1203,9 +1205,8 @@ class Drawing(bonsai.core.tool.Drawing): ifc_file = tool.Ifc.get() pset = tool.Pset.get_element_pset(element, "EPset_Annotation") if not pset: - pset = ifcopenshell.api.run("pset.add_pset", ifc_file, product=element, name="EPset_Annotation") - ifcopenshell.api.run( - "pset.edit_pset", + pset = ifcopenshell.api.pset.add_pset(ifc_file, product=element, name="EPset_Annotation") + ifcopenshell.api.pset.edit_pset( ifc_file, pset=pset, properties={"Newline_At": newline_at}, diff --git a/src/bonsai/bonsai/tool/feature.py b/src/bonsai/bonsai/tool/feature.py index a24ddeabc1..adc6cd9528 100644 --- a/src/bonsai/bonsai/tool/feature.py +++ b/src/bonsai/bonsai/tool/feature.py @@ -23,6 +23,7 @@ import bonsai.tool as tool import bonsai.bim.helper import bonsai.core.geometry import ifcopenshell +import ifcopenshell.api.feature import ifcopenshell.util.representation from typing import TYPE_CHECKING from collections.abc import Iterable @@ -57,9 +58,7 @@ class Feature(bonsai.core.tool.Feature): element_had_openings = tool.Geometry.has_openings(featured_element) body_context = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body") - ifcopenshell.api.run( - "feature.add_feature", tool.Ifc.get(), feature=feature_element, element=featured_element - ) + ifcopenshell.api.feature.add_feature(tool.Ifc.get(), feature=feature_element, element=featured_element) if tool.Ifc.is_moved(feature_obj): bonsai.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=feature_obj) diff --git a/src/bonsai/bonsai/tool/geometry.py b/src/bonsai/bonsai/tool/geometry.py index c27b803c6b..90a12250cd 100644 --- a/src/bonsai/bonsai/tool/geometry.py +++ b/src/bonsai/bonsai/tool/geometry.py @@ -31,6 +31,7 @@ import ifcopenshell.api.boundary import ifcopenshell.api.geometry import ifcopenshell.api.grid import ifcopenshell.api.profile +import ifcopenshell.api.pset import ifcopenshell.api.root import ifcopenshell.api.style import ifcopenshell.geom @@ -2250,7 +2251,7 @@ class Geometry(bonsai.core.tool.Geometry): pset = ifcopenshell.util.element.get_pset(new[0], "BBIM_Linked_Aggregate") if pset: pset = tool.Ifc.get().by_id(pset["id"]) - ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), product=new[0], pset=pset) + ifcopenshell.api.pset.remove_pset(tool.Ifc.get(), product=new[0], pset=pset) if new[0].is_a("IfcElementAssembly"): linked_aggregate_group = [ diff --git a/src/bonsai/bonsai/tool/ifcgit.py b/src/bonsai/bonsai/tool/ifcgit.py index 30e2712a7a..8a1a988b0b 100644 --- a/src/bonsai/bonsai/tool/ifcgit.py +++ b/src/bonsai/bonsai/tool/ifcgit.py @@ -31,11 +31,15 @@ from typing import TYPE_CHECKING, Union, Literal, Any os.environ["GIT_PYTHON_REFRESH"] = "quiet" try: import git + import git.exc + import git.objects except ImportError: print("Warning: GitPython not available.") if TYPE_CHECKING: import git + import git.exc + import git.objects from bonsai.bim.module.ifcgit.prop import IfcGitProperties diff --git a/src/bonsai/bonsai/tool/model.py b/src/bonsai/bonsai/tool/model.py index 7ecd510c85..4b1524db18 100644 --- a/src/bonsai/bonsai/tool/model.py +++ b/src/bonsai/bonsai/tool/model.py @@ -690,10 +690,10 @@ class Model(bonsai.core.tool.Model): data.extend(boolean_ids) data = list(set(data)) else: - pset = ifcopenshell.api.run("pset.add_pset", tool.Ifc.get(), product=element, name="BBIM_Boolean") + pset = ifcopenshell.api.pset.add_pset(tool.Ifc.get(), product=element, name="BBIM_Boolean") data = boolean_ids data = tool.Ifc.get().createIfcText(json.dumps(data)) - ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties={"Data": data}) + ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties={"Data": data}) @classmethod def unmark_manual_booleans(cls, element: ifcopenshell.entity_instance, boolean_ids: list[int]) -> None: @@ -712,9 +712,9 @@ class Model(bonsai.core.tool.Model): pset = tool.Ifc.get().by_id(pset["id"]) if data: data = tool.Ifc.get().createIfcText(json.dumps(data)) - ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties={"Data": data}) + ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties={"Data": data}) else: - ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), product=element, pset=pset) + ifcopenshell.api.pset.remove_pset(tool.Ifc.get(), product=element, pset=pset) @classmethod def get_flow_segment_axis(cls, obj: bpy.types.Object) -> tuple[Vector, Vector]: @@ -880,7 +880,7 @@ class Model(bonsai.core.tool.Model): # can be reverted later. array_pset_data = array_pset.get("Data", None) array_pset = tool.Ifc.get().by_id(array_pset["id"]) - ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), product=element, pset=array_pset) + ifcopenshell.api.pset.remove_pset(tool.Ifc.get(), product=element, pset=array_pset) # remove constraints obj = tool.Ifc.get_object(element) @@ -899,8 +899,7 @@ class Model(bonsai.core.tool.Model): obj = tool.Ifc.get_object(element) array_pset = tool.Pset.get_element_pset(element, "BBIM_Array") default_data = tool.Ifc.get().createIfcText('[{"children": []}]') - ifcopenshell.api.run( - "pset.edit_pset", + ifcopenshell.api.pset.edit_pset( tool.Ifc.get(), pset=array_pset, properties={"Parent": element.GlobalId, "Data": default_data}, @@ -909,7 +908,7 @@ class Model(bonsai.core.tool.Model): tool.Model.regenerate_array(obj, array_data) json_data = tool.Ifc.get().createIfcText(json.dumps(array_data)) - ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=array_pset, properties={"Data": json_data}) + ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=array_pset, properties={"Data": json_data}) for i in range(len(array_data)): tool.Blender.Modifier.Array.set_children_lock_state(element, i, True) @@ -1007,7 +1006,7 @@ class Model(bonsai.core.tool.Model): if array_i in array_layers_to_apply: for child_element in children_elements: pset = tool.Pset.get_element_pset(child_element, "BBIM_Array") - ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), product=child_element, pset=pset) + ifcopenshell.api.pset.remove_pset(tool.Ifc.get(), product=child_element, pset=pset) array["children"] = [] array["count"] = 1 @@ -1034,10 +1033,10 @@ class Model(bonsai.core.tool.Model): old_representation = tool.Geometry.resolve_mapped_representation(old_representation) for inverse in ifc_file.get_inverse(old_representation): ifcopenshell.util.element.replace_attribute(inverse, old_representation, new_representation) - ifcopenshell.api.run("geometry.remove_representation", ifc_file, representation=old_representation) + ifcopenshell.api.geometry.remove_representation(ifc_file, representation=old_representation) else: - ifcopenshell.api.run( - "geometry.assign_representation", ifc_file, product=ifc_element, representation=new_representation + ifcopenshell.api.geometry.assign_representation( + ifc_file, product=ifc_element, representation=new_representation ) bonsai.core.geometry.switch_representation( tool.Ifc, @@ -1559,8 +1558,8 @@ class Model(bonsai.core.tool.Model): opening, "Model", "Body", "MODEL_VIEW" ) old_representation = tool.Geometry.resolve_mapped_representation(old_representation) - ifcopenshell.api.run( - "geometry.unassign_representation", ifc_file, product=opening, representation=old_representation + ifcopenshell.api.geometry.unassign_representation( + ifc_file, product=opening, representation=old_representation ) new_representation = FilledOpeningGenerator().generate_opening_from_filling( @@ -1570,7 +1569,7 @@ class Model(bonsai.core.tool.Model): for inverse in ifc_file.get_inverse(old_representation): ifcopenshell.util.element.replace_attribute(inverse, old_representation, new_representation) - ifcopenshell.api.run("geometry.remove_representation", ifc_file, representation=old_representation) + ifcopenshell.api.geometry.remove_representation(ifc_file, representation=old_representation) has_replaced_opening_representation = True diff --git a/src/bonsai/bonsai/tool/pset_template.py b/src/bonsai/bonsai/tool/pset_template.py index 4cbaf7f808..54d35790ab 100644 --- a/src/bonsai/bonsai/tool/pset_template.py +++ b/src/bonsai/bonsai/tool/pset_template.py @@ -24,6 +24,7 @@ import ifcopenshell.util.attribute import ifcopenshell.util.element import bonsai.core.tool import bonsai.tool as tool +import bonsai.bim from pathlib import Path from typing import Literal, final, TYPE_CHECKING from bonsai.bim.ifc import IfcStore diff --git a/src/bonsai/bonsai/tool/root.py b/src/bonsai/bonsai/tool/root.py index 004a60999a..36c4631307 100644 --- a/src/bonsai/bonsai/tool/root.py +++ b/src/bonsai/bonsai/tool/root.py @@ -20,6 +20,9 @@ from __future__ import annotations import bpy import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.feature +import ifcopenshell.api.geometry +import ifcopenshell.api.root import ifcopenshell.api.style import ifcopenshell.util.representation import ifcopenshell.util.element @@ -285,11 +288,8 @@ class Root(bonsai.core.tool.Root): filling_obj = tool.Ifc.get_object(new_subelement) existing_opening_occurrence = subelement.FillsVoids[0].RelatingOpeningElement - opening = ifcopenshell.api.run( - "root.copy_class", tool.Ifc.get(), product=existing_opening_occurrence - ) - ifcopenshell.api.run( - "geometry.edit_object_placement", + opening = ifcopenshell.api.root.copy_class(tool.Ifc.get(), product=existing_opening_occurrence) + ifcopenshell.api.geometry.edit_object_placement( tool.Ifc.get(), product=opening, matrix=ifcopenshell.util.placement.get_local_placement(opening.ObjectPlacement), @@ -300,17 +300,16 @@ class Root(bonsai.core.tool.Root): existing_opening_occurrence, "Model", "Body", "MODEL_VIEW" ) representation = ifcopenshell.util.representation.resolve_representation(representation) - mapped_representation = ifcopenshell.api.run( - "geometry.map_representation", tool.Ifc.get(), representation=representation + mapped_representation = ifcopenshell.api.geometry.map_representation( + tool.Ifc.get(), representation=representation ) - ifcopenshell.api.run( - "geometry.assign_representation", + ifcopenshell.api.geometry.assign_representation( tool.Ifc.get(), product=opening, representation=mapped_representation, ) - ifcopenshell.api.run("feature.add_feature", tool.Ifc.get(), feature=opening, element=element) - ifcopenshell.api.run("feature.add_filling", tool.Ifc.get(), opening=opening, element=filling) + ifcopenshell.api.feature.add_feature(tool.Ifc.get(), feature=opening, element=element) + ifcopenshell.api.feature.add_filling(tool.Ifc.get(), opening=opening, element=filling) voided_objs = [voided_obj] # Openings affect all subelements of an aggregate @@ -344,8 +343,7 @@ class Root(bonsai.core.tool.Root): new_related_element = old_to_new.get(data["related_element"])[0] except: continue - ifcopenshell.api.run( - "geometry.connect_path", + ifcopenshell.api.geometry.connect_path( tool.Ifc.get(), relating_element=new_relating_element, related_element=new_related_element, diff --git a/src/bonsai/docs/guides/development/hello_world.rst b/src/bonsai/docs/guides/development/hello_world.rst index 0fdc43c272..4665299a5d 100644 --- a/src/bonsai/docs/guides/development/hello_world.rst +++ b/src/bonsai/docs/guides/development/hello_world.rst @@ -273,9 +273,11 @@ Here's an example of it in action: .. code-block:: python - import ifcopenshell.api - ifcopenshell.api.run("grid.create_grid_axis", model, ...) - ifcopenshell.api.run("structural.add_structural_load", model, ...) + import ifcopenshell.api.grid + import ifcopenshell.api.structural + + ifcopenshell.api.grid.create_grid_axis(model, ...) + ifcopenshell.api.structural.add_structural_load(model, ...) Because the API performs all the IFC manipulations to achieve a usecase, no further interaction is required in a typical native IFC authoring environment. diff --git a/src/bonsai/docs/guides/development/undo_system.rst b/src/bonsai/docs/guides/development/undo_system.rst index a123e8f96e..f6f29b331a 100644 --- a/src/bonsai/docs/guides/development/undo_system.rst +++ b/src/bonsai/docs/guides/development/undo_system.rst @@ -62,7 +62,7 @@ Instead, stuff happens in Blender operators. return IfcStore.execute_ifc_operator(self, context) def _execute(self, context): - ifcopenshell.api.run("foo.bar", tool.Ifc.get()) + ifcopenshell.api.foo.bar( tool.Ifc.get()) return {"FINISHED"} When your operator manipulates (creates, removes, or edits) IFC data directly or diff --git a/src/bonsai/scripts/bonsai_translations.py b/src/bonsai/scripts/bonsai_translations.py index 205d92d8dc..de7f613210 100644 --- a/src/bonsai/scripts/bonsai_translations.py +++ b/src/bonsai/scripts/bonsai_translations.py @@ -274,8 +274,10 @@ if BPY_IS_LOADED: f"Couldn't find locale path in the source directory, creating dummy directory: {source_locale_path}.", ) - from ui_translate.settings import settings as ui_translate_settings - from ui_translate.update_ui import UI_OT_i18n_updatetranslation_init_settings + from ui_translate.settings import settings as ui_translate_settings # pyright: ignore[reportMissingImports] + from ui_translate.update_ui import ( # pyright: ignore[reportMissingImports] + UI_OT_i18n_updatetranslation_init_settings, + ) i18n_settings = context.window_manager.i18n_update_settings if not i18n_settings.is_init: diff --git a/src/bonsai/scripts/extract.py b/src/bonsai/scripts/extract.py index 11c5a17833..aa5d233dfa 100644 --- a/src/bonsai/scripts/extract.py +++ b/src/bonsai/scripts/extract.py @@ -17,7 +17,7 @@ # along with Bonsai. If not, see . import xml.sax, json, copy, pathlib -from bs4 import BeautifulSoup +from bs4 import BeautifulSoup # pyright: ignore[reportMissingModuleSource] import sys sys.setrecursionlimit(100) diff --git a/src/bonsai/scripts/gbxml.py b/src/bonsai/scripts/gbxml.py index 3b8c3542cb..8d23fe6018 100644 --- a/src/bonsai/scripts/gbxml.py +++ b/src/bonsai/scripts/gbxml.py @@ -23,8 +23,9 @@ import sys # sys.path.append('C:\Program Files\Python37\Lib\site-packages') import lxml -import bspy -from bspy import Gbxml +import lxml.etree +import bspy # pyright: ignore[reportMissingImports] +from bspy import Gbxml # pyright: ignore[reportMissingImports] class GbxmlExporter: diff --git a/src/bonsai/scripts/generate_au_library.py b/src/bonsai/scripts/generate_au_library.py index b350de2ff6..044f2fb090 100644 --- a/src/bonsai/scripts/generate_au_library.py +++ b/src/bonsai/scripts/generate_au_library.py @@ -22,6 +22,14 @@ import bpy import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.context +import ifcopenshell.api.geometry +import ifcopenshell.api.material +import ifcopenshell.api.project +import ifcopenshell.api.pset +import ifcopenshell.api.root +import ifcopenshell.api.style +import ifcopenshell.api.unit import bonsai.tool as tool @@ -32,32 +40,26 @@ class LibraryGenerator: self.materials = {} - self.file = ifcopenshell.api.run("project.create_file") - self.project = ifcopenshell.api.run( - "root.create_entity", self.file, ifc_class="IfcProject", name="Australian Library" + self.file = ifcopenshell.api.project.create_file() + self.project = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject", name="Australian Library" ) - self.library = ifcopenshell.api.run( - "root.create_entity", self.file, ifc_class="IfcProjectLibrary", name="Australian Library" + self.library = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProjectLibrary", name="Australian Library") + ifcopenshell.api.project.assign_declaration(self.file, definitions=[self.library], relating_context=self.project ) - ifcopenshell.api.run( - "project.assign_declaration", self.file, definitions=[self.library], relating_context=self.project - ) - unit = ifcopenshell.api.run("unit.add_si_unit", self.file, unit_type="LENGTHUNIT", prefix="MILLI") - ifcopenshell.api.run("unit.assign_unit", self.file, units=[unit]) + unit = ifcopenshell.api.unit.add_si_unit(self.file, unit_type="LENGTHUNIT", prefix="MILLI") + ifcopenshell.api.unit.assign_unit(self.file, units=[unit]) - model = ifcopenshell.api.run("context.add_context", self.file, context_type="Model") - plan = ifcopenshell.api.run("context.add_context", self.file, context_type="Plan") + model = ifcopenshell.api.context.add_context(self.file, context_type="Model") + plan = ifcopenshell.api.context.add_context(self.file, context_type="Plan") self.representations = { - "model_body": ifcopenshell.api.run( - "context.add_context", + "model_body": ifcopenshell.api.context.add_context( self.file, context_type="Model", context_identifier="Body", target_view="MODEL_VIEW", parent=model, ), - "plan_body": ifcopenshell.api.run( - "context.add_context", + "plan_body": ifcopenshell.api.context.add_context( self.file, context_type="Plan", context_identifier="Annotation", @@ -81,7 +83,7 @@ class LibraryGenerator: } for name, data in self.materials.items(): - self.materials[name]["ifc"] = ifcopenshell.api.run("material.add_material", self.file, name=name) + self.materials[name]["ifc"] = ifcopenshell.api.material.add_material(self.file, name=name) self.materials[name]["ifc"].Category = data["Category"] self.layer_types = { @@ -121,12 +123,12 @@ class LibraryGenerator: self.layer_types[name]["ifc"] = self.create_layer_set_type(name, data) product = self.create_layer_type("IfcCoveringType", "DEMO20", 0.02) - pset = ifcopenshell.api.run("pset.add_pset", self.file, product=product, name="EPset_Parametric") - ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"LayerSetDirection": "AXIS2"}) + pset = ifcopenshell.api.pset.add_pset( self.file, product=product, name="EPset_Parametric") + ifcopenshell.api.pset.edit_pset( self.file, pset=pset, properties={"LayerSetDirection": "AXIS2"}) product = self.create_layer_type("IfcCoveringType", "DEMO30", 0.03) - pset = ifcopenshell.api.run("pset.add_pset", self.file, product=product, name="EPset_Parametric") - ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"LayerSetDirection": "AXIS3"}) + pset = ifcopenshell.api.pset.add_pset( self.file, product=product, name="EPset_Parametric") + ifcopenshell.api.pset.edit_pset( self.file, pset=pset, properties={"LayerSetDirection": "AXIS3"}) self.create_layer_type("IfcRampType", "DEMO200", 0.2) @@ -186,44 +188,41 @@ class LibraryGenerator: self.file.write("bonsai-au-library.ifc") def create_layer_set_type(self, name, data): - element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=data["type"], name=name) + element = ifcopenshell.api.root.create_entity( self.file, ifc_class=data["type"], name=name) element.Description = data["Description"] - rel = ifcopenshell.api.run("material.assign_material", self.file, products=[element], type="IfcMaterialLayerSet") + rel = ifcopenshell.api.material.assign_material( self.file, products=[element], type="IfcMaterialLayerSet") layer_set = rel.RelatingMaterial for layer_data in data["Layers"]: - layer = ifcopenshell.api.run( - "material.add_layer", self.file, layer_set=layer_set, material=self.materials[layer_data[1]]["ifc"] + layer = ifcopenshell.api.material.add_layer( self.file, layer_set=layer_set, material=self.materials[layer_data[1]]["ifc"] ) layer.Name = layer_data[0] layer.LayerThickness = layer_data[2] - ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library) + ifcopenshell.api.project.assign_declaration( self.file, definitions=[element], relating_context=self.library) return element def create_layer_type(self, ifc_class, name, thickness): - element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name) - rel = ifcopenshell.api.run("material.assign_material", self.file, products=[element], type="IfcMaterialLayerSet") + element = ifcopenshell.api.root.create_entity( self.file, ifc_class=ifc_class, name=name) + rel = ifcopenshell.api.material.assign_material( self.file, products=[element], type="IfcMaterialLayerSet") layer_set = rel.RelatingMaterial - layer = ifcopenshell.api.run("material.add_layer", self.file, layer_set=layer_set, material=self.materials["TBD"]["ifc"]) + layer = ifcopenshell.api.material.add_layer( self.file, layer_set=layer_set, material=self.materials["TBD"]["ifc"]) layer.LayerThickness = thickness - ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library) + ifcopenshell.api.project.assign_declaration( self.file, definitions=[element], relating_context=self.library) return element def create_profile_type(self, ifc_class, name, profile): - element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name) - rel = ifcopenshell.api.run("material.assign_material", self.file, products=[element], type="IfcMaterialProfileSet") + element = ifcopenshell.api.root.create_entity( self.file, ifc_class=ifc_class, name=name) + rel = ifcopenshell.api.material.assign_material( self.file, products=[element], type="IfcMaterialProfileSet") profile_set = rel.RelatingMaterial - material_profile = ifcopenshell.api.run( - "material.add_profile", self.file, profile_set=profile_set, material=self.materials["TBD"]["ifc"] + material_profile = ifcopenshell.api.material.add_profile( self.file, profile_set=profile_set, material=self.materials["TBD"]["ifc"] ) - ifcopenshell.api.run("material.assign_profile", self.file, material_profile=material_profile, profile=profile) - ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library) + ifcopenshell.api.material.assign_profile( self.file, material_profile=material_profile, profile=profile) + ifcopenshell.api.project.assign_declaration( self.file, definitions=[element], relating_context=self.library) def create_type(self, ifc_class, name, representations): - element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name) + element = ifcopenshell.api.root.create_entity( self.file, ifc_class=ifc_class, name=name) for rep_name, obj_name in representations.items(): obj = bpy.data.objects.get(obj_name) - representation = ifcopenshell.api.run( - "geometry.add_representation", + representation = ifcopenshell.api.geometry.add_representation( self.file, context=self.representations[rep_name], blender_object=obj, @@ -232,9 +231,8 @@ class LibraryGenerator: ) styles = [] for slot in obj.material_slots: - style = ifcopenshell.api.run("style.add_style", self.file, name=slot.material.name) - ifcopenshell.api.run( - "style.add_surface_style", + style = ifcopenshell.api.style.add_style( self.file, name=slot.material.name) + ifcopenshell.api.style.add_surface_style( self.file, style=style, ifc_class="IfcSurfaceStyleRendering", @@ -242,13 +240,11 @@ class LibraryGenerator: ) styles.append(style) if styles: - ifcopenshell.api.run( - "style.assign_representation_styles", self.file, shape_representation=representation, styles=styles + ifcopenshell.api.style.assign_representation_styles( self.file, shape_representation=representation, styles=styles ) - ifcopenshell.api.run( - "geometry.assign_representation", self.file, product=element, representation=representation + ifcopenshell.api.geometry.assign_representation( self.file, product=element, representation=representation ) - ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library) + ifcopenshell.api.project.assign_declaration( self.file, definitions=[element], relating_context=self.library) LibraryGenerator().generate() diff --git a/src/bonsai/scripts/generate_entourage_library.py b/src/bonsai/scripts/generate_entourage_library.py index e11930faca..78ed71ac6a 100644 --- a/src/bonsai/scripts/generate_entourage_library.py +++ b/src/bonsai/scripts/generate_entourage_library.py @@ -20,6 +20,12 @@ import os import bpy import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.context +import ifcopenshell.api.geometry +import ifcopenshell.api.project +import ifcopenshell.api.root +import ifcopenshell.api.style +import ifcopenshell.api.unit import bonsai.tool as tool from pathlib import Path @@ -36,46 +42,40 @@ class LibraryGenerator: self.materials = {} - self.file = ifcopenshell.api.run("project.create_file") - self.project = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject", name=library_name) - self.library = ifcopenshell.api.run( - "root.create_entity", self.file, ifc_class="IfcProjectLibrary", name=library_name + self.file = ifcopenshell.api.project.create_file() + self.project = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject", name=library_name) + self.library = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProjectLibrary", name=library_name) + ifcopenshell.api.project.assign_declaration( + self.file, definitions=[self.library], relating_context=self.project ) - ifcopenshell.api.run( - "project.assign_declaration", self.file, definitions=[self.library], relating_context=self.project - ) - unit = ifcopenshell.api.run("unit.add_si_unit", self.file, unit_type="LENGTHUNIT", prefix="MILLI") - ifcopenshell.api.run("unit.assign_unit", self.file, units=[unit]) + unit = ifcopenshell.api.unit.add_si_unit(self.file, unit_type="LENGTHUNIT", prefix="MILLI") + ifcopenshell.api.unit.assign_unit(self.file, units=[unit]) - model = ifcopenshell.api.run("context.add_context", self.file, context_type="Model") - plan = ifcopenshell.api.run("context.add_context", self.file, context_type="Plan") + model = ifcopenshell.api.context.add_context(self.file, context_type="Model") + plan = ifcopenshell.api.context.add_context(self.file, context_type="Plan") self.representations = { - "Model/Body/MODEL_VIEW": ifcopenshell.api.run( - "context.add_context", + "Model/Body/MODEL_VIEW": ifcopenshell.api.context.add_context( self.file, context_type="Model", context_identifier="Body", target_view="MODEL_VIEW", parent=model, ), - "Plan/Body/PLAN_VIEW": ifcopenshell.api.run( - "context.add_context", + "Plan/Body/PLAN_VIEW": ifcopenshell.api.context.add_context( self.file, context_type="Plan", context_identifier="Body", target_view="PLAN_VIEW", parent=plan, ), - "Model/Body/PLAN_VIEW": ifcopenshell.api.run( - "context.add_context", + "Model/Body/PLAN_VIEW": ifcopenshell.api.context.add_context( self.file, context_type="Model", context_identifier="Body", target_view="PLAN_VIEW", parent=model, ), - "Model/Body/SECTION_VIEW": ifcopenshell.api.run( - "context.add_context", + "Model/Body/SECTION_VIEW": ifcopenshell.api.context.add_context( self.file, context_type="Model", context_identifier="Body", @@ -100,13 +100,12 @@ class LibraryGenerator: self.file.write(output_filename) def create_type(self, ifc_class, name, representations): - element = ifcopenshell.api.run( - "root.create_entity", self.file, ifc_class=ifc_class, predefined_type="ENTOURAGE", name=name + element = ifcopenshell.api.root.create_entity( + self.file, ifc_class=ifc_class, predefined_type="ENTOURAGE", name=name ) for rep_name, obj_name in representations.items(): obj = bpy.data.objects.get(obj_name) - representation = ifcopenshell.api.run( - "geometry.add_representation", + representation = ifcopenshell.api.geometry.add_representation( self.file, context=self.representations[rep_name], blender_object=obj, @@ -115,9 +114,8 @@ class LibraryGenerator: ) styles = [] for slot in obj.material_slots: - style = ifcopenshell.api.run("style.add_style", self.file, name=slot.material.name) - ifcopenshell.api.run( - "style.add_surface_style", + style = ifcopenshell.api.style.add_style(self.file, name=slot.material.name) + ifcopenshell.api.style.add_surface_style( self.file, style=style, ifc_class="IfcSurfaceStyleShading", @@ -125,15 +123,11 @@ class LibraryGenerator: ) styles.append(style) if styles: - ifcopenshell.api.run( - "style.assign_representation_styles", self.file, shape_representation=representation, styles=styles + ifcopenshell.api.style.assign_representation_styles( + self.file, shape_representation=representation, styles=styles ) - ifcopenshell.api.run( - "geometry.assign_representation", self.file, product=element, representation=representation - ) - ifcopenshell.api.run( - "project.assign_declaration", self.file, definitions=[element], relating_context=self.library - ) + ifcopenshell.api.geometry.assign_representation(self.file, product=element, representation=representation) + ifcopenshell.api.project.assign_declaration(self.file, definitions=[element], relating_context=self.library) if __name__ == "__main__": diff --git a/src/bonsai/scripts/generate_furniture_library.py b/src/bonsai/scripts/generate_furniture_library.py index 7fd8cf4a81..844b60823a 100644 --- a/src/bonsai/scripts/generate_furniture_library.py +++ b/src/bonsai/scripts/generate_furniture_library.py @@ -19,6 +19,13 @@ import numpy as np import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.context +import ifcopenshell.api.geometry +import ifcopenshell.api.material +import ifcopenshell.api.project +import ifcopenshell.api.root +import ifcopenshell.api.style +import ifcopenshell.api.unit import ifcopenshell.util.element from math import cos, tan, pi from pathlib import Path @@ -37,30 +44,26 @@ class LibraryGenerator: self.materials = {} - self.file = ifcopenshell.api.run("project.create_file") - self.project = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject", name=library_name) - self.library = ifcopenshell.api.run( - "root.create_entity", self.file, ifc_class="IfcProjectLibrary", name=library_name + self.file = ifcopenshell.api.project.create_file() + self.project = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject", name=library_name) + self.library = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProjectLibrary", name=library_name) + ifcopenshell.api.project.assign_declaration( + self.file, definitions=[self.library], relating_context=self.project ) - ifcopenshell.api.run( - "project.assign_declaration", self.file, definitions=[self.library], relating_context=self.project - ) - unit = ifcopenshell.api.run("unit.add_si_unit", self.file, unit_type="LENGTHUNIT", prefix="MILLI") - ifcopenshell.api.run("unit.assign_unit", self.file, units=[unit]) + unit = ifcopenshell.api.unit.add_si_unit(self.file, unit_type="LENGTHUNIT", prefix="MILLI") + ifcopenshell.api.unit.assign_unit(self.file, units=[unit]) - model = ifcopenshell.api.run("context.add_context", self.file, context_type="Model") - plan = ifcopenshell.api.run("context.add_context", self.file, context_type="Plan") + model = ifcopenshell.api.context.add_context(self.file, context_type="Model") + plan = ifcopenshell.api.context.add_context(self.file, context_type="Plan") self.representations = { - "model_body": ifcopenshell.api.run( - "context.add_context", + "model_body": ifcopenshell.api.context.add_context( self.file, context_type="Model", context_identifier="Body", target_view="MODEL_VIEW", parent=model, ), - "plan_body": ifcopenshell.api.run( - "context.add_context", + "plan_body": ifcopenshell.api.context.add_context( self.file, context_type="Plan", context_identifier="Body", @@ -1847,78 +1850,58 @@ class LibraryGenerator: self.file.write(output_filename) def create_explicit_type(self, ifc_class, name, representation_3d, representation_2d, **params): - element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name) + element = ifcopenshell.api.root.create_entity(self.file, ifc_class=ifc_class, name=name) for param, value in params.items(): setattr(element, param, value) - ifcopenshell.api.run( - "geometry.assign_representation", self.file, product=element, representation=representation_3d - ) - ifcopenshell.api.run( - "geometry.assign_representation", self.file, product=element, representation=representation_2d - ) - ifcopenshell.api.run( - "project.assign_declaration", self.file, definitions=[element], relating_context=self.library - ) + ifcopenshell.api.geometry.assign_representation(self.file, product=element, representation=representation_3d) + ifcopenshell.api.geometry.assign_representation(self.file, product=element, representation=representation_2d) + ifcopenshell.api.project.assign_declaration(self.file, definitions=[element], relating_context=self.library) return element def create_layer_set_type(self, name, data): - element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=data["type"], name=name) + element = ifcopenshell.api.root.create_entity(self.file, ifc_class=data["type"], name=name) element.Description = data["Description"] - rel = ifcopenshell.api.run( - "material.assign_material", self.file, products=[element], type="IfcMaterialLayerSet" - ) + rel = ifcopenshell.api.material.assign_material(self.file, products=[element], type="IfcMaterialLayerSet") layer_set = rel.RelatingMaterial for layer_data in data["Layers"]: - layer = ifcopenshell.api.run( - "material.add_layer", self.file, layer_set=layer_set, material=self.materials[layer_data[1]]["ifc"] + layer = ifcopenshell.api.material.add_layer( + self.file, layer_set=layer_set, material=self.materials[layer_data[1]]["ifc"] ) layer.Name = layer_data[0] layer.LayerThickness = layer_data[2] - ifcopenshell.api.run( - "project.assign_declaration", self.file, definitions=[element], relating_context=self.library - ) + ifcopenshell.api.project.assign_declaration(self.file, definitions=[element], relating_context=self.library) return element def create_layer_type(self, ifc_class, name, thickness): - element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name) - rel = ifcopenshell.api.run( - "material.assign_material", self.file, products=[element], type="IfcMaterialLayerSet" - ) + element = ifcopenshell.api.root.create_entity(self.file, ifc_class=ifc_class, name=name) + rel = ifcopenshell.api.material.assign_material(self.file, products=[element], type="IfcMaterialLayerSet") layer_set = rel.RelatingMaterial - layer = ifcopenshell.api.run( - "material.add_layer", self.file, layer_set=layer_set, material=self.materials["TBD"]["ifc"] + layer = ifcopenshell.api.material.add_layer( + self.file, layer_set=layer_set, material=self.materials["TBD"]["ifc"] ) layer.LayerThickness = thickness - ifcopenshell.api.run( - "project.assign_declaration", self.file, definitions=[element], relating_context=self.library - ) + ifcopenshell.api.project.assign_declaration(self.file, definitions=[element], relating_context=self.library) return element def create_profile_type(self, ifc_class, name, profile): - element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name) - rel = ifcopenshell.api.run( - "material.assign_material", self.file, products=[element], type="IfcMaterialProfileSet" - ) + element = ifcopenshell.api.root.create_entity(self.file, ifc_class=ifc_class, name=name) + rel = ifcopenshell.api.material.assign_material(self.file, products=[element], type="IfcMaterialProfileSet") profile_set = rel.RelatingMaterial - material_profile = ifcopenshell.api.run( - "material.add_profile", + material_profile = ifcopenshell.api.material.add_profile( self.file, profile_set=profile_set, material=self.material, # material=self.materials["TBD"]["ifc"] ) - ifcopenshell.api.run("material.assign_profile", self.file, material_profile=material_profile, profile=profile) - ifcopenshell.api.run( - "project.assign_declaration", self.file, definitions=[element], relating_context=self.library - ) + ifcopenshell.api.material.assign_profile(self.file, material_profile=material_profile, profile=profile) + ifcopenshell.api.project.assign_declaration(self.file, definitions=[element], relating_context=self.library) def create_type(self, ifc_class, name, representations): - element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name) + element = ifcopenshell.api.root.create_entity(self.file, ifc_class=ifc_class, name=name) for rep_name, obj_name in representations.items(): obj = bpy.data.objects.get(obj_name) - representation = ifcopenshell.api.run( - "geometry.add_representation", + representation = ifcopenshell.api.geometry.add_representation( self.file, context=self.representations[rep_name], blender_object=obj, @@ -1927,9 +1910,8 @@ class LibraryGenerator: ) styles = [] for slot in obj.material_slots: - style = ifcopenshell.api.run("style.add_style", self.file, name=slot.material.name) - ifcopenshell.api.run( - "style.add_surface_style", + style = ifcopenshell.api.style.add_style(self.file, name=slot.material.name) + ifcopenshell.api.style.add_surface_style( self.file, style=style, ifc_class="IfcSurfaceStyleRendering", @@ -1937,15 +1919,11 @@ class LibraryGenerator: ) styles.append(style) if styles: - ifcopenshell.api.run( - "style.assign_representation_styles", self.file, shape_representation=representation, styles=styles + ifcopenshell.api.style.assign_representation_styles( + self.file, shape_representation=representation, styles=styles ) - ifcopenshell.api.run( - "geometry.assign_representation", self.file, product=element, representation=representation - ) - ifcopenshell.api.run( - "project.assign_declaration", self.file, definitions=[element], relating_context=self.library - ) + ifcopenshell.api.geometry.assign_representation(self.file, product=element, representation=representation) + ifcopenshell.api.project.assign_declaration(self.file, definitions=[element], relating_context=self.library) if __name__ == "__main__": diff --git a/src/bonsai/scripts/generate_landscape_library.py b/src/bonsai/scripts/generate_landscape_library.py index 381e517d92..01e694e9d0 100644 --- a/src/bonsai/scripts/generate_landscape_library.py +++ b/src/bonsai/scripts/generate_landscape_library.py @@ -22,6 +22,13 @@ import csv import random import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.context +import ifcopenshell.api.geometry +import ifcopenshell.api.project +import ifcopenshell.api.root +import ifcopenshell.api.style +import ifcopenshell.api.unit +import ifcopenshell.util.unit import bonsai.tool as tool from math import cos, sin, tan, pi from pathlib import Path @@ -313,46 +320,40 @@ class LibraryGenerator: self.materials = {} - self.file = ifcopenshell.api.run("project.create_file") - self.project = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject", name=library_name) - self.library = ifcopenshell.api.run( - "root.create_entity", self.file, ifc_class="IfcProjectLibrary", name=library_name + self.file = ifcopenshell.api.project.create_file() + self.project = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject", name=library_name) + self.library = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProjectLibrary", name=library_name) + ifcopenshell.api.project.assign_declaration( + self.file, definitions=[self.library], relating_context=self.project ) - ifcopenshell.api.run( - "project.assign_declaration", self.file, definitions=[self.library], relating_context=self.project - ) - unit = ifcopenshell.api.run("unit.add_si_unit", self.file, unit_type="LENGTHUNIT", prefix="MILLI") - ifcopenshell.api.run("unit.assign_unit", self.file, units=[unit]) + unit = ifcopenshell.api.unit.add_si_unit(self.file, unit_type="LENGTHUNIT", prefix="MILLI") + ifcopenshell.api.unit.assign_unit(self.file, units=[unit]) - model = ifcopenshell.api.run("context.add_context", self.file, context_type="Model") - plan = ifcopenshell.api.run("context.add_context", self.file, context_type="Plan") + model = ifcopenshell.api.context.add_context(self.file, context_type="Model") + plan = ifcopenshell.api.context.add_context(self.file, context_type="Plan") self.representations = { - "Model/Body/MODEL_VIEW": ifcopenshell.api.run( - "context.add_context", + "Model/Body/MODEL_VIEW": ifcopenshell.api.context.add_context( self.file, context_type="Model", context_identifier="Body", target_view="MODEL_VIEW", parent=model, ), - "Plan/Body/PLAN_VIEW": ifcopenshell.api.run( - "context.add_context", + "Plan/Body/PLAN_VIEW": ifcopenshell.api.context.add_context( self.file, context_type="Plan", context_identifier="Body", target_view="PLAN_VIEW", parent=plan, ), - "Model/Body/PLAN_VIEW": ifcopenshell.api.run( - "context.add_context", + "Model/Body/PLAN_VIEW": ifcopenshell.api.context.add_context( self.file, context_type="Model", context_identifier="Body", target_view="PLAN_VIEW", parent=model, ), - "Model/Body/SECTION_VIEW": ifcopenshell.api.run( - "context.add_context", + "Model/Body/SECTION_VIEW": ifcopenshell.api.context.add_context( self.file, context_type="Model", context_identifier="Body", @@ -435,27 +436,20 @@ class LibraryGenerator: } def create_explicit_type(self, ifc_class, name, representation_3d, representation_2d, **params): - element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name) + element = ifcopenshell.api.root.create_entity(self.file, ifc_class=ifc_class, name=name) for param, value in params.items(): setattr(element, param, value) - ifcopenshell.api.run( - "geometry.assign_representation", self.file, product=element, representation=representation_3d - ) - ifcopenshell.api.run( - "geometry.assign_representation", self.file, product=element, representation=representation_2d - ) - ifcopenshell.api.run( - "project.assign_declaration", self.file, definitions=[element], relating_context=self.library - ) + ifcopenshell.api.geometry.assign_representation(self.file, product=element, representation=representation_3d) + ifcopenshell.api.geometry.assign_representation(self.file, product=element, representation=representation_2d) + ifcopenshell.api.project.assign_declaration(self.file, definitions=[element], relating_context=self.library) return element def create_type(self, ifc_class, name, representations): - element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name) + element = ifcopenshell.api.root.create_entity(self.file, ifc_class=ifc_class, name=name) for rep_name, obj_name in representations.items(): obj = bpy.data.objects.get(obj_name) - representation = ifcopenshell.api.run( - "geometry.add_representation", + representation = ifcopenshell.api.geometry.add_representation( self.file, context=self.representations[rep_name], blender_object=obj, @@ -464,9 +458,8 @@ class LibraryGenerator: ) styles = [] for slot in obj.material_slots: - style = ifcopenshell.api.run("style.add_style", self.file, name=slot.material.name) - ifcopenshell.api.run( - "style.add_surface_style", + style = ifcopenshell.api.style.add_style(self.file, name=slot.material.name) + ifcopenshell.api.style.add_surface_style( self.file, style=style, ifc_class="IfcSurfaceStyleShading", @@ -474,15 +467,11 @@ class LibraryGenerator: ) styles.append(style) if styles: - ifcopenshell.api.run( - "style.assign_representation_styles", self.file, shape_representation=representation, styles=styles + ifcopenshell.api.style.assign_representation_styles( + self.file, shape_representation=representation, styles=styles ) - ifcopenshell.api.run( - "geometry.assign_representation", self.file, product=element, representation=representation - ) - ifcopenshell.api.run( - "project.assign_declaration", self.file, definitions=[element], relating_context=self.library - ) + ifcopenshell.api.geometry.assign_representation(self.file, product=element, representation=representation) + ifcopenshell.api.project.assign_declaration(self.file, definitions=[element], relating_context=self.library) if __name__ == "__main__": diff --git a/src/bonsai/scripts/generate_site_library.py b/src/bonsai/scripts/generate_site_library.py index 7008bcf43a..e42ad4e4f2 100644 --- a/src/bonsai/scripts/generate_site_library.py +++ b/src/bonsai/scripts/generate_site_library.py @@ -19,6 +19,12 @@ import bpy import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.context +import ifcopenshell.api.geometry +import ifcopenshell.api.project +import ifcopenshell.api.root +import ifcopenshell.api.style +import ifcopenshell.api.unit import bonsai.tool as tool @@ -27,27 +33,25 @@ class LibraryGenerator: ifcopenshell.api.pre_listeners = {} ifcopenshell.api.post_listeners = {} - self.file = ifcopenshell.api.run("project.create_file") - self.project = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject", name="Bonsai Demo") - self.library = ifcopenshell.api.run( - "root.create_entity", self.file, ifc_class="IfcProjectLibrary", name="Bonsai Demo Library" + self.file = ifcopenshell.api.project.create_file() + self.project = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject", name="Bonsai Demo") + self.library = ifcopenshell.api.root.create_entity( + self.file, ifc_class="IfcProjectLibrary", name="Bonsai Demo Library" ) - ifcopenshell.api.run( - "project.assign_declaration", self.file, definitions=[self.library], relating_context=self.library + ifcopenshell.api.project.assign_declaration( + self.file, definitions=[self.library], relating_context=self.library ) - ifcopenshell.api.run("unit.assign_unit", self.file, length={"is_metric": True, "raw": "METERS"}) - model = ifcopenshell.api.run("context.add_context", self.file, context_type="Model") + ifcopenshell.api.unit.assign_unit(self.file, length={"is_metric": True, "raw": "METERS"}) + model = ifcopenshell.api.context.add_context(self.file, context_type="Model") self.representations = { - "body": ifcopenshell.api.run( - "context.add_context", + "body": ifcopenshell.api.context.add_context( self.file, context_type="Model", context_identifier="Body", target_view="MODEL_VIEW", parent=model, ), - "clearance": ifcopenshell.api.run( - "context.add_context", + "clearance": ifcopenshell.api.context.add_context( self.file, context_type="Model", context_identifier="Clearance", @@ -67,11 +71,10 @@ class LibraryGenerator: self.file.write("bonsai-site-library.ifc") def create_type(self, ifc_class, name, representations): - element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name) + element = ifcopenshell.api.root.create_entity(self.file, ifc_class=ifc_class, name=name) for rep_name, obj_name in representations.items(): obj = bpy.data.objects.get(obj_name) - representation = ifcopenshell.api.run( - "geometry.add_representation", + representation = ifcopenshell.api.geometry.add_representation( self.file, context=self.representations[rep_name], blender_object=obj, @@ -80,9 +83,8 @@ class LibraryGenerator: ) styles = [] for slot in obj.material_slots: - style = ifcopenshell.api.run("style.add_style", self.file, name=slot.material.name) - ifcopenshell.api.run( - "style.add_surface_style", + style = ifcopenshell.api.style.add_style(self.file, name=slot.material.name) + ifcopenshell.api.style.add_surface_style( self.file, style=style, ifc_class="IfcSurfaceStyleRendering", @@ -90,15 +92,11 @@ class LibraryGenerator: ) styles.append(style) if styles: - ifcopenshell.api.run( - "style.assign_representation_styles", self.file, shape_representation=representation, styles=styles + ifcopenshell.api.style.assign_representation_styles( + self.file, shape_representation=representation, styles=styles ) - ifcopenshell.api.run( - "geometry.assign_representation", self.file, product=element, representation=representation - ) - ifcopenshell.api.run( - "project.assign_declaration", self.file, definitions=[element], relating_context=self.library - ) + ifcopenshell.api.geometry.assign_representation(self.file, product=element, representation=representation) + ifcopenshell.api.project.assign_declaration(self.file, definitions=[element], relating_context=self.library) LibraryGenerator().generate() diff --git a/src/bonsai/scripts/generate_steel_profiles_library.py b/src/bonsai/scripts/generate_steel_profiles_library.py index a20f26e268..086c918689 100644 --- a/src/bonsai/scripts/generate_steel_profiles_library.py +++ b/src/bonsai/scripts/generate_steel_profiles_library.py @@ -21,7 +21,11 @@ import ifcopenshell import ifcopenshell.api -import boltspy as bolts +import ifcopenshell.api.material +import ifcopenshell.api.project +import ifcopenshell.api.root +import ifcopenshell.api.unit +import boltspy as bolts # pyright: ignore[reportMissingImports] from math import cos, pi from pathlib import Path from ifcopenshell.util.shape_builder import ShapeBuilder, V, ifc_safe_vector_type @@ -35,29 +39,26 @@ class LibraryGenerator: self.materials = {} - self.file = ifcopenshell.api.run("project.create_file") - self.project = ifcopenshell.api.run( - "root.create_entity", self.file, ifc_class="IfcProject", name=f"{parse_profiles_type} Steel Profiles Library" + self.file = ifcopenshell.api.project.create_file() + self.project = ifcopenshell.api.root.create_entity( self.file, ifc_class="IfcProject", name=f"{parse_profiles_type} Steel Profiles Library" ) - self.library = ifcopenshell.api.run( - "root.create_entity", self.file, ifc_class="IfcProjectLibrary", name=f"{parse_profiles_type} Steel Profiles Library" + self.library = ifcopenshell.api.root.create_entity( self.file, ifc_class="IfcProjectLibrary", name=f"{parse_profiles_type} Steel Profiles Library" ) - ifcopenshell.api.run( - "project.assign_declaration", self.file, definitions=[self.library], relating_context=self.project + ifcopenshell.api.project.assign_declaration( self.file, definitions=[self.library], relating_context=self.project ) dim_exponents = self.file.createIfcDimensionalExponents(0, 0, 0, 0, 0, 0, 0) - length_unit = ifcopenshell.api.run("unit.add_si_unit", self.file, unit_type="LENGTHUNIT", prefix="MILLI") + length_unit = ifcopenshell.api.unit.add_si_unit( self.file, unit_type="LENGTHUNIT", prefix="MILLI") builder = ShapeBuilder(self.file) # define angle unit to use degrees for IfcPlaneAngleMeasure: # https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcPlaneAngleMeasure.htm - angle_unit = ifcopenshell.api.run("unit.add_si_unit", self.file, unit_type="PLANEANGLEUNIT") + angle_unit = ifcopenshell.api.unit.add_si_unit( self.file, unit_type="PLANEANGLEUNIT") value_component = self.file.createIfcReal(pi/180) angle_unit = self.file.createIfcMeasureWithUnit(ValueComponent=value_component, UnitComponent=angle_unit) angle_unit = self.file.createIfcConversionBasedUnit(Name="degree", Dimensions=dim_exponents, UnitType="PLANEANGLEUNIT", ConversionFactor=angle_unit) - ifcopenshell.api.run("unit.assign_unit", self.file, units=[length_unit, angle_unit]) + ifcopenshell.api.unit.assign_unit( self.file, units=[length_unit, angle_unit]) - self.material = ifcopenshell.api.run("material.add_material", self.file, name="Unknown") + self.material = ifcopenshell.api.material.add_material( self.file, name="Unknown") # NOTE: parameters could be optional (example: welded i-beams don't have FilletRadius) profiles_translation = { @@ -174,15 +175,14 @@ class LibraryGenerator: print('-----------------------') def create_profile_type(self, ifc_class, name, profile): - element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name) - rel = ifcopenshell.api.run("material.assign_material", self.file, products=[element], type="IfcMaterialProfileSet") + element = ifcopenshell.api.root.create_entity( self.file, ifc_class=ifc_class, name=name) + rel = ifcopenshell.api.material.assign_material( self.file, products=[element], type="IfcMaterialProfileSet") profile_set = rel.RelatingMaterial - material_profile = ifcopenshell.api.run( - "material.add_profile", self.file, profile_set=profile_set, material=self.material + material_profile = ifcopenshell.api.material.add_profile( self.file, profile_set=profile_set, material=self.material # material=self.materials["TBD"]["ifc"] ) - ifcopenshell.api.run("material.assign_profile", self.file, material_profile=material_profile, profile=profile) - ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library) + ifcopenshell.api.material.assign_profile( self.file, material_profile=material_profile, profile=profile) + ifcopenshell.api.project.assign_declaration( self.file, definitions=[element], relating_context=self.library) def create_double_l_profile(self, profile, resulting_profile_name=None, profiles_gap=0, mode = "LLBB"): def create_derived_profile(profile, mirrored=False): diff --git a/src/bonsai/scripts/geonodes_modifier_prototype.py b/src/bonsai/scripts/geonodes_modifier_prototype.py index 8b2fa77f73..1b3dbfd8ab 100644 --- a/src/bonsai/scripts/geonodes_modifier_prototype.py +++ b/src/bonsai/scripts/geonodes_modifier_prototype.py @@ -18,6 +18,8 @@ import ifcopenshell +import ifcopenshell.api.pset +import ifcopenshell.util.element import bonsai.tool as tool import bpy @@ -67,9 +69,8 @@ def update_geometry_data(): if pset: pset = tool.Ifc.get().by_id(pset["id"]) else: - pset = ifcopenshell.api.run("pset.add_pset", tool.Ifc.get(), product=element, name="BBIM_Geonodes") - ifcopenshell.api.run( - "pset.edit_pset", + pset = ifcopenshell.api.pset.add_pset(tool.Ifc.get(), product=element, name="BBIM_Geonodes") + ifcopenshell.api.pset.edit_pset( tool.Ifc.get(), pset=pset, properties={"Data": json.dumps(geo_data, default=list)}, diff --git a/src/bonsai/scripts/obj2ifc-meshlab.py b/src/bonsai/scripts/obj2ifc-meshlab.py index 9b9a367c78..1d2739ca21 100644 --- a/src/bonsai/scripts/obj2ifc-meshlab.py +++ b/src/bonsai/scripts/obj2ifc-meshlab.py @@ -19,9 +19,16 @@ # This can be packaged with `pyinstaller --onefile --hidden-import numpy --collect-all ifcopenshell --clean obj2ifc.py` import argparse -import pymeshlab +import pymeshlab # pyright: ignore[reportMissingImports] import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.aggregate +import ifcopenshell.api.context +import ifcopenshell.api.geometry +import ifcopenshell.api.project +import ifcopenshell.api.root +import ifcopenshell.api.spatial +import ifcopenshell.api.unit import ifcopenshell.api.owner.settings import ifcopenshell.guid from pathlib import Path @@ -86,9 +93,7 @@ class Obj2Ifc: Name=mesh.label() or self.basename, Representation=representation, ) - ifcopenshell.api.run( - "spatial.assign_container", self.file, products=[product], relating_structure=self.storey - ) + ifcopenshell.api.spatial.assign_container(self.file, products=[product], relating_structure=self.storey) product.ObjectPlacement = self.placement self.file.write(self.outfile) @@ -99,42 +104,39 @@ class Obj2Ifc: return [coordinates[0], -coordinates[2], coordinates[1]] def create_ifc_file(self, version): - self.file = ifcopenshell.api.run("project.create_file", version=version) - person = ifcopenshell.api.run("owner.add_person", self.file) + self.file = ifcopenshell.api.project.create_file(version=version) + person = ifcopenshell.api.owner.add_person(self.file) person[0] = person.GivenName = None person.FamilyName = "user" - org = ifcopenshell.api.run("owner.add_organisation", self.file) + org = ifcopenshell.api.owner.add_organisation(self.file) org[0] = None org.Name = "template" - user = ifcopenshell.api.run("owner.add_person_and_organisation", self.file, person=person, organisation=org) - application = ifcopenshell.api.run("owner.add_application", self.file) + user = ifcopenshell.api.owner.add_person_and_organisation(self.file, person=person, organisation=org) + application = ifcopenshell.api.owner.add_application(self.file) ifcopenshell.api.owner.settings.get_user = lambda ifc: user ifcopenshell.api.owner.settings.get_application = lambda ifc: application - project = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject", name=self.basename) - lengthunit = ifcopenshell.api.run("unit.add_si_unit", self.file, unit_type="LENGTHUNIT") - ifcopenshell.api.run("unit.assign_unit", self.file, units=[lengthunit]) - model = ifcopenshell.api.run("context.add_context", self.file, context_type="Model") - self.context = ifcopenshell.api.run( - "context.add_context", + project = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject", name=self.basename) + lengthunit = ifcopenshell.api.unit.add_si_unit(self.file, unit_type="LENGTHUNIT") + ifcopenshell.api.unit.assign_unit(self.file, units=[lengthunit]) + model = ifcopenshell.api.context.add_context(self.file, context_type="Model") + self.context = ifcopenshell.api.context.add_context( self.file, context_type="Model", context_identifier="Body", target_view="MODEL_VIEW", parent=model, ) - site = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSite", name="My Site") - building = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding", name="My Building") - self.storey = ifcopenshell.api.run( - "root.create_entity", self.file, ifc_class="IfcBuildingStorey", name="My Storey" - ) - ifcopenshell.api.run("aggregate.assign_object", self.file, products=[site], relating_object=project) - ifcopenshell.api.run("aggregate.assign_object", self.file, products=[building], relating_object=site) - ifcopenshell.api.run("aggregate.assign_object", self.file, products=[self.storey], relating_object=building) + site = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcSite", name="My Site") + building = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcBuilding", name="My Building") + self.storey = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcBuildingStorey", name="My Storey") + ifcopenshell.api.aggregate.assign_object(self.file, products=[site], relating_object=project) + ifcopenshell.api.aggregate.assign_object(self.file, products=[building], relating_object=site) + ifcopenshell.api.aggregate.assign_object(self.file, products=[self.storey], relating_object=building) - ifcopenshell.api.run("geometry.edit_object_placement", self.file, product=site) - ifcopenshell.api.run("geometry.edit_object_placement", self.file, product=building) - ifcopenshell.api.run("geometry.edit_object_placement", self.file, product=self.storey) + ifcopenshell.api.geometry.edit_object_placement(self.file, product=site) + ifcopenshell.api.geometry.edit_object_placement(self.file, product=building) + ifcopenshell.api.geometry.edit_object_placement(self.file, product=self.storey) self.origin = self.file.createIfcAxis2Placement3D( self.file.createIfcCartesianPoint((0.0, 0.0, 0.0)), @@ -142,7 +144,7 @@ class Obj2Ifc: self.file.createIfcDirection((1.0, 0.0, 0.0)), ) self.placement = self.file.createIfcLocalPlacement(self.storey.ObjectPlacement, self.origin) - self.history = ifcopenshell.api.run("owner.create_owner_history", self.file) + self.history = ifcopenshell.api.owner.create_owner_history(self.file) if __name__ == "__main__": diff --git a/src/bonsai/scripts/obj2ifc.py b/src/bonsai/scripts/obj2ifc.py index af08a32248..dc91cedfd5 100644 --- a/src/bonsai/scripts/obj2ifc.py +++ b/src/bonsai/scripts/obj2ifc.py @@ -19,9 +19,16 @@ # This can be packaged with `pyinstaller --onefile --hidden-import numpy --collect-all ifcopenshell --clean obj2ifc.py` import argparse -import pywavefront +import pywavefront # pyright: ignore[reportMissingImports] import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.aggregate +import ifcopenshell.api.context +import ifcopenshell.api.geometry +import ifcopenshell.api.project +import ifcopenshell.api.root +import ifcopenshell.api.spatial +import ifcopenshell.api.unit import ifcopenshell.api.owner.settings import ifcopenshell.guid from pathlib import Path @@ -80,9 +87,7 @@ class Obj2Ifc: Name=mesh.name or self.basename, Representation=representation, ) - ifcopenshell.api.run( - "spatial.assign_container", self.file, products=[product], relating_structure=self.storey - ) + ifcopenshell.api.spatial.assign_container(self.file, products=[product], relating_structure=self.storey) product.ObjectPlacement = self.placement self.file.write(self.outfile) @@ -92,42 +97,39 @@ class Obj2Ifc: return [coordinates[0], -coordinates[2], coordinates[1]] def create_ifc_file(self, version): - self.file = ifcopenshell.api.run("project.create_file", version=version) - person = ifcopenshell.api.run("owner.add_person", self.file) + self.file = ifcopenshell.api.project.create_file(version=version) + person = ifcopenshell.api.owner.add_person(self.file) person[0] = person.GivenName = None person.FamilyName = "user" - org = ifcopenshell.api.run("owner.add_organisation", self.file) + org = ifcopenshell.api.owner.add_organisation(self.file) org[0] = None org.Name = "template" - user = ifcopenshell.api.run("owner.add_person_and_organisation", self.file, person=person, organisation=org) - application = ifcopenshell.api.run("owner.add_application", self.file) + user = ifcopenshell.api.owner.add_person_and_organisation(self.file, person=person, organisation=org) + application = ifcopenshell.api.owner.add_application(self.file) ifcopenshell.api.owner.settings.get_user = lambda ifc: user ifcopenshell.api.owner.settings.get_application = lambda ifc: application - project = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject", name=self.basename) - lengthunit = ifcopenshell.api.run("unit.add_si_unit", self.file, unit_type="LENGTHUNIT") - ifcopenshell.api.run("unit.assign_unit", self.file, units=[lengthunit]) - model = ifcopenshell.api.run("context.add_context", self.file, context_type="Model") - self.context = ifcopenshell.api.run( - "context.add_context", + project = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject", name=self.basename) + lengthunit = ifcopenshell.api.unit.add_si_unit(self.file, unit_type="LENGTHUNIT") + ifcopenshell.api.unit.assign_unit(self.file, units=[lengthunit]) + model = ifcopenshell.api.context.add_context(self.file, context_type="Model") + self.context = ifcopenshell.api.context.add_context( self.file, context_type="Model", context_identifier="Body", target_view="MODEL_VIEW", parent=model, ) - site = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSite", name="My Site") - building = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding", name="My Building") - self.storey = ifcopenshell.api.run( - "root.create_entity", self.file, ifc_class="IfcBuildingStorey", name="My Storey" - ) - ifcopenshell.api.run("aggregate.assign_object", self.file, products=[site], relating_object=project) - ifcopenshell.api.run("aggregate.assign_object", self.file, products=[building], relating_object=site) - ifcopenshell.api.run("aggregate.assign_object", self.file, products=[self.storey], relating_object=building) + site = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcSite", name="My Site") + building = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcBuilding", name="My Building") + self.storey = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcBuildingStorey", name="My Storey") + ifcopenshell.api.aggregate.assign_object(self.file, products=[site], relating_object=project) + ifcopenshell.api.aggregate.assign_object(self.file, products=[building], relating_object=site) + ifcopenshell.api.aggregate.assign_object(self.file, products=[self.storey], relating_object=building) - ifcopenshell.api.run("geometry.edit_object_placement", self.file, product=site) - ifcopenshell.api.run("geometry.edit_object_placement", self.file, product=building) - ifcopenshell.api.run("geometry.edit_object_placement", self.file, product=self.storey) + ifcopenshell.api.geometry.edit_object_placement(self.file, product=site) + ifcopenshell.api.geometry.edit_object_placement(self.file, product=building) + ifcopenshell.api.geometry.edit_object_placement(self.file, product=self.storey) self.origin = self.file.createIfcAxis2Placement3D( self.file.createIfcCartesianPoint((0.0, 0.0, 0.0)), @@ -135,7 +137,7 @@ class Obj2Ifc: self.file.createIfcDirection((1.0, 0.0, 0.0)), ) self.placement = self.file.createIfcLocalPlacement(self.storey.ObjectPlacement, self.origin) - self.history = ifcopenshell.api.run("owner.create_owner_history", self.file) + self.history = ifcopenshell.api.owner.create_owner_history(self.file) if __name__ == "__main__": diff --git a/src/bonsai/scripts/replace_drawing_path.py b/src/bonsai/scripts/replace_drawing_path.py index b874614502..eeca3911e0 100644 --- a/src/bonsai/scripts/replace_drawing_path.py +++ b/src/bonsai/scripts/replace_drawing_path.py @@ -29,6 +29,8 @@ It works on the active ifc file (if exists). import bonsai.tool as tool import ifcopenshell +import ifcopenshell.api.pset +import ifcopenshell.util.element import sys @@ -53,8 +55,7 @@ for annotation in annotations: wrong_sep = "\\" if platform == "win32": wrong_sep = "/" - ifcopenshell.api.run( - "pset.edit_pset", + ifcopenshell.api.pset.edit_pset( file, pset=pset_ifc, properties={ diff --git a/src/bonsai/scripts/shape_builder_examples.py b/src/bonsai/scripts/shape_builder_examples.py index 806a7b9f8a..3141f99144 100644 --- a/src/bonsai/scripts/shape_builder_examples.py +++ b/src/bonsai/scripts/shape_builder_examples.py @@ -1,4 +1,9 @@ import ifcopenshell +import ifcopenshell.api.context +import ifcopenshell.api.geometry +import ifcopenshell.api.project +import ifcopenshell.api.root +import ifcopenshell.api.unit from ifcopenshell.util.shape_builder import ShapeBuilder from mathutils import Vector @@ -76,30 +81,28 @@ def generate_desk_test(): def mirror_placement_test(): - ifc_file = ifcopenshell.api.run("project.create_file") - project = ifcopenshell.api.run( - "root.create_entity", ifc_file, ifc_class="IfcProject", name=f"Non-structural assets library" + ifc_file = ifcopenshell.api.project.create_file() + project = ifcopenshell.api.root.create_entity( + ifc_file, ifc_class="IfcProject", name=f"Non-structural assets library" ) - library = ifcopenshell.api.run( - "root.create_entity", ifc_file, ifc_class="IfcProjectLibrary", name=f"Non-structural assets library" + library = ifcopenshell.api.root.create_entity( + ifc_file, ifc_class="IfcProjectLibrary", name=f"Non-structural assets library" ) - ifcopenshell.api.run("project.assign_declaration", ifc_file, definitions=[library], relating_context=project) - unit = ifcopenshell.api.run("unit.add_si_unit", ifc_file, unit_type="LENGTHUNIT", prefix="MILLI") - ifcopenshell.api.run("unit.assign_unit", ifc_file, units=[unit]) - model = ifcopenshell.api.run("context.add_context", ifc_file, context_type="Model") - plan = ifcopenshell.api.run("context.add_context", ifc_file, context_type="Plan") + ifcopenshell.api.project.assign_declaration(ifc_file, definitions=[library], relating_context=project) + unit = ifcopenshell.api.unit.add_si_unit(ifc_file, unit_type="LENGTHUNIT", prefix="MILLI") + ifcopenshell.api.unit.assign_unit(ifc_file, units=[unit]) + model = ifcopenshell.api.context.add_context(ifc_file, context_type="Model") + plan = ifcopenshell.api.context.add_context(ifc_file, context_type="Plan") representations = { - "body": ifcopenshell.api.run( - "context.add_context", + "body": ifcopenshell.api.context.add_context( ifc_file, context_type="Model", context_identifier="Body", target_view="MODEL_VIEW", parent=model, ), - "annotation": ifcopenshell.api.run( - "context.add_context", + "annotation": ifcopenshell.api.context.add_context( ifc_file, context_type="Plan", context_identifier="Annotation", @@ -136,38 +139,36 @@ def mirror_placement_test(): representation_3d = builder.get_representation(context=representations["body"], items=items_3d) - element = ifcopenshell.api.run("root.create_entity", ifc_file, ifc_class="IfcFurnitureType", name="test") - ifcopenshell.api.run("geometry.assign_representation", ifc_file, product=element, representation=representation_3d) - ifcopenshell.api.run("project.assign_declaration", ifc_file, definitions=[element], relating_context=library) + element = ifcopenshell.api.root.create_entity(ifc_file, ifc_class="IfcFurnitureType", name="test") + ifcopenshell.api.geometry.assign_representation(ifc_file, product=element, representation=representation_3d) + ifcopenshell.api.project.assign_declaration(ifc_file, definitions=[element], relating_context=library) ifc_file.write("tmp.ifc") def curve_between_two_points_test(): - ifc_file = ifcopenshell.api.run("project.create_file") - project = ifcopenshell.api.run( - "root.create_entity", ifc_file, ifc_class="IfcProject", name=f"Non-structural assets library" + ifc_file = ifcopenshell.api.project.create_file() + project = ifcopenshell.api.root.create_entity( + ifc_file, ifc_class="IfcProject", name=f"Non-structural assets library" ) - library = ifcopenshell.api.run( - "root.create_entity", ifc_file, ifc_class="IfcProjectLibrary", name=f"Non-structural assets library" + library = ifcopenshell.api.root.create_entity( + ifc_file, ifc_class="IfcProjectLibrary", name=f"Non-structural assets library" ) - ifcopenshell.api.run("project.assign_declaration", ifc_file, definitions=[library], relating_context=project) - unit = ifcopenshell.api.run("unit.add_si_unit", ifc_file, unit_type="LENGTHUNIT", prefix="MILLI") - ifcopenshell.api.run("unit.assign_unit", ifc_file, units=[unit]) - model = ifcopenshell.api.run("context.add_context", ifc_file, context_type="Model") - plan = ifcopenshell.api.run("context.add_context", ifc_file, context_type="Plan") + ifcopenshell.api.project.assign_declaration(ifc_file, definitions=[library], relating_context=project) + unit = ifcopenshell.api.unit.add_si_unit(ifc_file, unit_type="LENGTHUNIT", prefix="MILLI") + ifcopenshell.api.unit.assign_unit(ifc_file, units=[unit]) + model = ifcopenshell.api.context.add_context(ifc_file, context_type="Model") + plan = ifcopenshell.api.context.add_context(ifc_file, context_type="Plan") representations = { - "body": ifcopenshell.api.run( - "context.add_context", + "body": ifcopenshell.api.context.add_context( ifc_file, context_type="Model", context_identifier="Body", target_view="MODEL_VIEW", parent=model, ), - "annotation": ifcopenshell.api.run( - "context.add_context", + "annotation": ifcopenshell.api.context.add_context( ifc_file, context_type="Plan", context_identifier="Annotation", @@ -199,9 +200,9 @@ def curve_between_two_points_test(): representation_2d = builder.get_representation(context=representations["annotation"], items=items_2d) print(representation_2d) - element = ifcopenshell.api.run("root.create_entity", ifc_file, ifc_class="IfcFurnitureType", name="test") - ifcopenshell.api.run("geometry.assign_representation", ifc_file, product=element, representation=representation_2d) - ifcopenshell.api.run("project.assign_declaration", ifc_file, definitions=[element], relating_context=library) + element = ifcopenshell.api.root.create_entity(ifc_file, ifc_class="IfcFurnitureType", name="test") + ifcopenshell.api.geometry.assign_representation(ifc_file, product=element, representation=representation_2d) + ifcopenshell.api.project.assign_declaration(ifc_file, definitions=[element], relating_context=library) ifc_file.write("tmp.ifc") diff --git a/src/bonsai/scripts/standalone_blender_import.py b/src/bonsai/scripts/standalone_blender_import.py index 3c04f24ddd..27dc84e07f 100644 --- a/src/bonsai/scripts/standalone_blender_import.py +++ b/src/bonsai/scripts/standalone_blender_import.py @@ -1,10 +1,11 @@ import ifcopenshell -import ifcopenshell.api import ifcopenshell.geom import multiprocessing class BlenderImporter: + file: ifcopenshell.file + def __init__(self): self.file = ifcopenshell.open("/home/dion/untitled.ifc") self.cache_path = "cache.h5" diff --git a/src/bonsai/scripts/standalone_drawer.py b/src/bonsai/scripts/standalone_drawer.py index f45435e522..320c474485 100644 --- a/src/bonsai/scripts/standalone_drawer.py +++ b/src/bonsai/scripts/standalone_drawer.py @@ -15,6 +15,7 @@ class LineworkContexts(NamedTuple): class Drawer: def execute(self): + ifc: ifcopenshell.file ifc = ifcopenshell.open(sys.argv[1]) self.camera_element = ifc.by_guid(sys.argv[2]) # Don't use draw.main() just whilst we're prototyping and experimenting diff --git a/src/bonsai/scripts/waldo.py b/src/bonsai/scripts/waldo.py index 15d8efcaa5..5ed734356c 100644 --- a/src/bonsai/scripts/waldo.py +++ b/src/bonsai/scripts/waldo.py @@ -1,15 +1,17 @@ import numpy as np import ifcopenshell +import ifcopenshell.api.aggregate +import ifcopenshell.api.context +import ifcopenshell.api.geometry +import ifcopenshell.api.material +import ifcopenshell.api.project import ifcopenshell.api.root +import ifcopenshell.api.spatial +import ifcopenshell.api.style import ifcopenshell.api.type import ifcopenshell.api.unit -import ifcopenshell.api.project -import ifcopenshell.api.context -import ifcopenshell.api.spatial -import ifcopenshell.api.material -import ifcopenshell.api.geometry +import ifcopenshell.util.placement import ifcopenshell.util.shape_builder -import ifcopenshell.util.element # https://stackoverflow.com/a/9184560/9627415 # Possible optimisation to linalg.norm? diff --git a/src/bonsai/test/tool/test_aggregate.py b/src/bonsai/test/tool/test_aggregate.py index 94130a5661..20c31cacdc 100644 --- a/src/bonsai/test/tool/test_aggregate.py +++ b/src/bonsai/test/tool/test_aggregate.py @@ -18,10 +18,11 @@ import bpy import ifcopenshell +import ifcopenshell.api.context import ifcopenshell.api.geometry import ifcopenshell.api.root +import ifcopenshell.api.spatial import ifcopenshell.api.unit -import ifcopenshell.api.context import ifcopenshell.util.shape_builder import bonsai.core.tool import bonsai.tool as tool @@ -140,5 +141,5 @@ class TestGetContainer(NewFile): tool.Ifc.set(ifc) element = ifc.createIfcWall() container = ifc.createIfcBuildingStorey() - ifcopenshell.api.run("spatial.assign_container", ifc, products=[element], relating_structure=container) + ifcopenshell.api.spatial.assign_container(ifc, products=[element], relating_structure=container) assert subject.get_container(element) == container diff --git a/src/bonsai/test/tool/test_brick.py b/src/bonsai/test/tool/test_brick.py index bdc5e34ddc..c17eb31f83 100644 --- a/src/bonsai/test/tool/test_brick.py +++ b/src/bonsai/test/tool/test_brick.py @@ -23,6 +23,8 @@ import brickschema.persistent from brickschema.namespaces import REF, A import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.aggregate +import ifcopenshell.api.root import ifcopenshell.guid import bonsai.core.tool import bonsai.tool as tool @@ -325,11 +327,11 @@ class TestGetConvertableBrickSystems(NewFile): class TestGetParentSpace(NewFile): def test_run(self): ifc = ifcopenshell.file() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcBuildingStorey") - subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcSpace") - project = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") - ifcopenshell.api.run("aggregate.assign_object", ifc, products=[subelement], relating_object=element) - ifcopenshell.api.run("aggregate.assign_object", ifc, products=[element], relating_object=project) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcBuildingStorey") + subelement = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcSpace") + project = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcProject") + ifcopenshell.api.aggregate.assign_object(ifc, products=[subelement], relating_object=element) + ifcopenshell.api.aggregate.assign_object(ifc, products=[element], relating_object=project) assert subject.get_parent_space(subelement) == element assert subject.get_parent_space(element) is None diff --git a/src/bonsai/test/tool/test_document.py b/src/bonsai/test/tool/test_document.py index d60b9fbe31..9e3556afd5 100644 --- a/src/bonsai/test/tool/test_document.py +++ b/src/bonsai/test/tool/test_document.py @@ -19,6 +19,7 @@ import bpy import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.document import bonsai.core.tool import bonsai.tool as tool from test.bim.bootstrap import NewFile @@ -170,7 +171,7 @@ class TestImportProjectDocuments(NewFile): ifc = ifcopenshell.file() tool.Ifc().set(ifc) ifc.createIfcProject() - document = ifcopenshell.api.run("document.add_information", ifc) + document = ifcopenshell.api.document.add_information(ifc) subject.import_project_documents() props = tool.Document.get_document_props() assert len(props.documents) == 1 @@ -185,8 +186,8 @@ class TestImportReferences(NewFile): ifc = ifcopenshell.file() tool.Ifc().set(ifc) ifc.createIfcProject() - document = ifcopenshell.api.run("document.add_information", ifc) - reference = ifcopenshell.api.run("document.add_reference", ifc, information=document) + document = ifcopenshell.api.document.add_information(ifc) + reference = ifcopenshell.api.document.add_reference(ifc, information=document) subject.import_references(document) props = tool.Document.get_document_props() assert len(props.documents) == 1 @@ -201,8 +202,8 @@ class TestImportSubdocuments(NewFile): ifc = ifcopenshell.file() tool.Ifc().set(ifc) ifc.createIfcProject() - document = ifcopenshell.api.run("document.add_information", ifc) - subdocument = ifcopenshell.api.run("document.add_information", ifc, parent=document) + document = ifcopenshell.api.document.add_information(ifc) + subdocument = ifcopenshell.api.document.add_information(ifc, parent=document) subject.import_subdocuments(document) props = tool.Document.get_document_props() assert len(props.documents) == 1 diff --git a/src/bonsai/test/tool/test_drawing.py b/src/bonsai/test/tool/test_drawing.py index ee9f8a7c50..35d771aef3 100644 --- a/src/bonsai/test/tool/test_drawing.py +++ b/src/bonsai/test/tool/test_drawing.py @@ -22,6 +22,9 @@ import numpy as np import bpy import mathutils import ifcopenshell +import ifcopenshell.api.drawing +import ifcopenshell.api.group +import ifcopenshell.api.pset import ifcopenshell.api.root import ifcopenshell.guid import ifcopenshell.util.element @@ -341,9 +344,9 @@ class TestGetDrawingGroup(NewFile): ifc = ifcopenshell.file() tool.Ifc.set(ifc) element = ifc.createIfcAnnotation() - group = ifcopenshell.api.run("group.add_group", ifc) + group = ifcopenshell.api.group.add_group(ifc) group.ObjectType = "DRAWING" - ifcopenshell.api.run("group.assign_group", ifc, products=[element], group=group) + ifcopenshell.api.group.assign_group(ifc, products=[element], group=group) assert subject.get_drawing_group(element) == group @@ -352,8 +355,8 @@ class TestGetDrawingTargetView(NewFile): ifc = ifcopenshell.file() tool.Ifc.set(ifc) element = ifc.createIfcAnnotation() - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="EPset_Drawing") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"TargetView": "PLAN_VIEW"}) + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="EPset_Drawing") + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"TargetView": "PLAN_VIEW"}) assert subject.get_drawing_target_view(element) == "PLAN_VIEW" @@ -362,8 +365,8 @@ class TestGetGroupElements(NewFile): ifc = ifcopenshell.file() tool.Ifc.set(ifc) element = ifc.createIfcAnnotation() - group = ifcopenshell.api.run("group.add_group", ifc) - ifcopenshell.api.run("group.assign_group", ifc, products=[element], group=group) + group = ifcopenshell.api.group.add_group(ifc) + ifcopenshell.api.group.assign_group(ifc, products=[element], group=group) assert subject.get_group_elements(group) == (element,) @@ -515,7 +518,7 @@ class TestGetAssignedProduct(NewFile): tool.Ifc.set(ifc) wall = ifc.createIfcWall() label = ifc.createIfcAnnotation() - ifcopenshell.api.run("drawing.assign_product", ifc, relating_product=wall, related_object=label) + ifcopenshell.api.drawing.assign_product(ifc, relating_product=wall, related_object=label) assert subject.get_assigned_product(label) == wall @@ -524,8 +527,8 @@ class TestImportDrawings(NewFile): ifc = ifcopenshell.file() tool.Ifc.set(ifc) drawing = ifc.createIfcAnnotation(Name="FOOBAR", ObjectType="DRAWING") - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=drawing, name="EPset_Drawing") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"TargetView": "PLAN_VIEW"}) + pset = ifcopenshell.api.pset.add_pset(ifc, product=drawing, name="EPset_Drawing") + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"TargetView": "PLAN_VIEW"}) subject.import_drawings() props = tool.Drawing.get_document_props() for d in props.drawings: @@ -635,7 +638,7 @@ class TestImportAssignedProduct(NewFile): tool.Ifc.set(ifc) wall = ifc.createIfcWall() label = ifc.createIfcAnnotation() - ifcopenshell.api.run("drawing.assign_product", ifc, relating_product=wall, related_object=label) + ifcopenshell.api.drawing.assign_product(ifc, relating_product=wall, related_object=label) wall_obj = bpy.data.objects.new("Object", None) label_obj = bpy.data.objects.new("Object", None) tool.Ifc.link(wall, wall_obj) @@ -794,7 +797,7 @@ class TestUpdateTextValue(NewFile): ifc = tool.Ifc.get() wall = ifc.createIfcWall(Name="Baz") label = ifc.by_type("IfcAnnotation")[0] - ifcopenshell.api.run("drawing.assign_product", ifc, relating_product=wall, related_object=label) + ifcopenshell.api.drawing.assign_product(ifc, relating_product=wall, related_object=label) ifc.by_type("IfcTextLiteralWithExtent")[0].Literal = "Foo {{Name}} Bar" @@ -808,10 +811,10 @@ class TestUpdateTextValue(NewFile): obj = bpy.data.objects["Object"] ifc = tool.Ifc.get() wall = ifc.createIfcWall() - pset = ifcopenshell.api.run("pset.add_pset", ifc, name="Custom_Pset", product=wall) - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Key": "Baz"}) + pset = ifcopenshell.api.pset.add_pset(ifc, name="Custom_Pset", product=wall) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Key": "Baz"}) label = ifc.by_type("IfcAnnotation")[0] - ifcopenshell.api.run("drawing.assign_product", ifc, relating_product=wall, related_object=label) + ifcopenshell.api.drawing.assign_product(ifc, relating_product=wall, related_object=label) ifc.by_type("IfcTextLiteralWithExtent")[0].Literal = "Foo {{Custom_Pset.Key}} Bar" diff --git a/src/bonsai/test/tool/test_geometry.py b/src/bonsai/test/tool/test_geometry.py index a392cd2ef3..aa9ca65211 100644 --- a/src/bonsai/test/tool/test_geometry.py +++ b/src/bonsai/test/tool/test_geometry.py @@ -21,6 +21,7 @@ import math import numpy as np import ifcopenshell import ifcopenshell.api.geometry +import ifcopenshell.api.root import ifcopenshell.api.type import bonsai.core.tool import bonsai.tool as tool @@ -202,7 +203,7 @@ class TestGetElementType(NewFile): ifc = tool.Ifc.get() element = ifc.createIfcWall() type = ifc.createIfcWallType() - ifcopenshell.api.run("type.assign_type", ifc, related_objects=[element], relating_type=type) + ifcopenshell.api.type.assign_type(ifc, related_objects=[element], relating_type=type) assert subject.get_element_type(element) == type @@ -212,7 +213,7 @@ class TestGetElementsOfType(NewFile): ifc = tool.Ifc.get() element = ifc.createIfcWall() type = ifc.createIfcWallType() - ifcopenshell.api.run("type.assign_type", ifc, related_objects=[element], relating_type=type) + ifcopenshell.api.type.assign_type(ifc, related_objects=[element], relating_type=type) assert subject.get_elements_of_type(type) == (element,) @@ -328,9 +329,9 @@ class TestRemoveConnection(NewFile): def test_run(self): ifc = ifcopenshell.file() tool.Ifc().set(ifc) - element1 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - element2 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - rel = ifcopenshell.api.run("geometry.connect_path", ifc, relating_element=element1, related_element=element2) + element1 = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + element2 = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + rel = ifcopenshell.api.geometry.connect_path(ifc, relating_element=element1, related_element=element2) subject.remove_connection(rel) assert not tool.Ifc.get().by_type("IfcRelConnectsPathElements") @@ -445,17 +446,17 @@ class TestSelectConnection(NewFile): ifc = ifcopenshell.file() tool.Ifc().set(ifc) - element1 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") + element1 = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") obj1 = bpy.data.objects.new("Object", None) bpy.context.scene.collection.objects.link(obj1) tool.Ifc.link(element1, obj1) - element2 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") + element2 = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") obj2 = bpy.data.objects.new("Object", None) bpy.context.scene.collection.objects.link(obj2) tool.Ifc.link(element2, obj2) - rel = ifcopenshell.api.run("geometry.connect_path", ifc, relating_element=element1, related_element=element2) + rel = ifcopenshell.api.geometry.connect_path(ifc, relating_element=element1, related_element=element2) subject.select_connection(rel) assert obj1 in bpy.context.selected_objects diff --git a/src/bonsai/test/tool/test_georeference.py b/src/bonsai/test/tool/test_georeference.py index 84173d79db..a6292abde4 100644 --- a/src/bonsai/test/tool/test_georeference.py +++ b/src/bonsai/test/tool/test_georeference.py @@ -20,6 +20,10 @@ import bpy import math import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.context +import ifcopenshell.api.georeference +import ifcopenshell.api.root +import ifcopenshell.api.unit import bonsai.core.tool import bonsai.tool as tool from mathutils import Vector @@ -36,8 +40,8 @@ class TestImportProjectedCRS(NewFile): def test_importing_nothing_with_no_georeferencing(self): ifc = ifcopenshell.file() tool.Ifc.set(ifc) - ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") - ifcopenshell.api.run("context.add_context", ifc, context_type="Model") + ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcProject") + ifcopenshell.api.context.add_context(ifc, context_type="Model") subject.import_projected_crs() props = tool.Georeference.get_georeference_props() assert len(props.projected_crs) == 0 @@ -45,9 +49,9 @@ class TestImportProjectedCRS(NewFile): def test_importing_projected_crs(self): ifc = ifcopenshell.file() tool.Ifc.set(ifc) - ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") - ifcopenshell.api.run("context.add_context", ifc, context_type="Model") - ifcopenshell.api.run("georeference.add_georeferencing", ifc) + ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcProject") + ifcopenshell.api.context.add_context(ifc, context_type="Model") + ifcopenshell.api.georeference.add_georeferencing(ifc) projected_crs = ifc.by_type("IfcProjectedCRS")[0] projected_crs.Name = "Name" projected_crs.Description = "Description" @@ -55,7 +59,7 @@ class TestImportProjectedCRS(NewFile): projected_crs.VerticalDatum = "VerticalDatum" projected_crs.MapProjection = "MapProjection" projected_crs.MapZone = "MapZone" - unit = ifcopenshell.api.run("unit.add_si_unit", ifc, unit_type="LENGTHUNIT") + unit = ifcopenshell.api.unit.add_si_unit(ifc, unit_type="LENGTHUNIT") projected_crs.MapUnit = unit subject.import_projected_crs() props = tool.Georeference.get_georeference_props() @@ -79,8 +83,8 @@ class TestImportCoordinateOperation(NewFile): def test_importing_nothing_with_no_georeferencing(self): ifc = ifcopenshell.file() tool.Ifc.set(ifc) - ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") - ifcopenshell.api.run("context.add_context", ifc, context_type="Model") + ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcProject") + ifcopenshell.api.context.add_context(ifc, context_type="Model") subject.import_coordinate_operation() props = tool.Georeference.get_georeference_props() assert len(props.coordinate_operation) == 0 @@ -88,9 +92,9 @@ class TestImportCoordinateOperation(NewFile): def test_importing_coordinate_operation(self): ifc = ifcopenshell.file() tool.Ifc.set(ifc) - ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") - ifcopenshell.api.run("context.add_context", ifc, context_type="Model") - ifcopenshell.api.run("georeference.add_georeferencing", ifc) + ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcProject") + ifcopenshell.api.context.add_context(ifc, context_type="Model") + ifcopenshell.api.georeference.add_georeferencing(ifc) map_conversion = ifc.by_type("IfcMapConversion")[0] map_conversion.Eastings = 1 map_conversion.Northings = 2 @@ -120,8 +124,8 @@ class TestImportTrueNorth(NewFile): def test_detecting_no_true_north(self): ifc = ifcopenshell.file() tool.Ifc.set(ifc) - ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") - ifcopenshell.api.run("context.add_context", ifc, context_type="Model") + ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcProject") + ifcopenshell.api.context.add_context(ifc, context_type="Model") subject.import_true_north() props = tool.Georeference.get_georeference_props() assert props.true_north_abscissa == "0" @@ -131,8 +135,8 @@ class TestImportTrueNorth(NewFile): def test_run(self): ifc = ifcopenshell.file() tool.Ifc.set(ifc) - ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") - context = ifcopenshell.api.run("context.add_context", ifc, context_type="Model") + ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcProject") + context = ifcopenshell.api.context.add_context(ifc, context_type="Model") context.TrueNorth = ifc.createIfcDirection((1.0, 2.0, 0.0)) subject.import_true_north() props = tool.Georeference.get_georeference_props() @@ -216,10 +220,10 @@ class TestGetCursorLocation(NewFile): def test_run(self): ifc = ifcopenshell.file() tool.Ifc.set(ifc) - ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") - ifcopenshell.api.run("context.add_context", ifc, context_type="Model") - unit = ifcopenshell.api.run("unit.add_si_unit", ifc, unit_type="LENGTHUNIT", prefix="MILLI") - ifcopenshell.api.run("unit.assign_unit", ifc, units=[unit]) + ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcProject") + ifcopenshell.api.context.add_context(ifc, context_type="Model") + unit = ifcopenshell.api.unit.add_si_unit(ifc, unit_type="LENGTHUNIT", prefix="MILLI") + ifcopenshell.api.unit.assign_unit(ifc, units=[unit]) assert bpy.context.scene bpy.context.scene.cursor.location = (1.0, 2.0, 3.0) assert subject.get_cursor_location() == [1000.0, 2000.0, 3000.0] @@ -228,13 +232,13 @@ class TestGetCursorLocation(NewFile): class TestXyz2Enh(NewFile): def test_run(self): ifc = ifcopenshell.file() - ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") + ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcProject") tool.Ifc.set(ifc) assert subject.xyz2enh((0.0, 0.0, 0.0)) == (0.0, 0.0, 0.0) def test_using_the_blender_offset(self): ifc = ifcopenshell.file() - ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") + ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcProject") tool.Ifc.set(ifc) props = tool.Georeference.get_georeference_props() props.has_blender_offset = True @@ -244,9 +248,9 @@ class TestXyz2Enh(NewFile): def test_using_the_map_conversion(self): ifc = ifcopenshell.file() tool.Ifc.set(ifc) - ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") - ifcopenshell.api.run("context.add_context", ifc, context_type="Model") - ifcopenshell.api.run("georeference.add_georeferencing", ifc) + ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcProject") + ifcopenshell.api.context.add_context(ifc, context_type="Model") + ifcopenshell.api.georeference.add_georeferencing(ifc) map_conversion = ifc.by_type("IfcMapConversion")[0] map_conversion.Eastings = 1.0 assert subject.xyz2enh((0.0, 0.0, 0.0)) == (1.0, 0.0, 0.0) @@ -257,9 +261,9 @@ class TestXyz2Enh(NewFile): props.blender_offset_x = "1.0" ifc = ifcopenshell.file() tool.Ifc.set(ifc) - ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") - ifcopenshell.api.run("context.add_context", ifc, context_type="Model") - ifcopenshell.api.run("georeference.add_georeferencing", ifc) + ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcProject") + ifcopenshell.api.context.add_context(ifc, context_type="Model") + ifcopenshell.api.georeference.add_georeferencing(ifc) map_conversion = ifc.by_type("IfcMapConversion")[0] map_conversion.Northings = 1.0 assert subject.xyz2enh((0.0, 0.0, 0.0)) == (1.0, 1.0, 0.0) @@ -268,13 +272,13 @@ class TestXyz2Enh(NewFile): class TestEnh2Xyz(NewFile): def test_run(self): ifc = ifcopenshell.file() - ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") + ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcProject") tool.Ifc.set(ifc) assert subject.enh2xyz((0.0, 0.0, 0.0)) == (0.0, 0.0, 0.0) def test_using_the_blender_offset(self): ifc = ifcopenshell.file() - ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") + ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcProject") tool.Ifc.set(ifc) props = tool.Georeference.get_georeference_props() props.has_blender_offset = True @@ -284,9 +288,9 @@ class TestEnh2Xyz(NewFile): def test_using_the_map_conversion(self): ifc = ifcopenshell.file() tool.Ifc.set(ifc) - ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") - ifcopenshell.api.run("context.add_context", ifc, context_type="Model") - ifcopenshell.api.run("georeference.add_georeferencing", ifc) + ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcProject") + ifcopenshell.api.context.add_context(ifc, context_type="Model") + ifcopenshell.api.georeference.add_georeferencing(ifc) map_conversion = ifc.by_type("IfcMapConversion")[0] map_conversion.Eastings = 1.0 assert subject.enh2xyz((0.0, 0.0, 0.0)) == (-1.0, 0.0, 0.0) @@ -297,9 +301,9 @@ class TestEnh2Xyz(NewFile): props.blender_offset_x = "1.0" ifc = ifcopenshell.file() tool.Ifc.set(ifc) - ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") - ifcopenshell.api.run("context.add_context", ifc, context_type="Model") - ifcopenshell.api.run("georeference.add_georeferencing", ifc) + ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcProject") + ifcopenshell.api.context.add_context(ifc, context_type="Model") + ifcopenshell.api.georeference.add_georeferencing(ifc) map_conversion = ifc.by_type("IfcMapConversion")[0] map_conversion.Northings = 1.0 assert subject.enh2xyz((0.0, 0.0, 0.0)) == (-1.0, -1.0, 0.0) diff --git a/src/bonsai/test/tool/test_material.py b/src/bonsai/test/tool/test_material.py index c980135b5a..ef423afb4c 100644 --- a/src/bonsai/test/tool/test_material.py +++ b/src/bonsai/test/tool/test_material.py @@ -21,6 +21,7 @@ import ifcopenshell import ifcopenshell.api import ifcopenshell.api.material import ifcopenshell.api.pset +import ifcopenshell.api.root import ifcopenshell.api.style import bonsai.core.tool import bonsai.tool as tool @@ -64,9 +65,9 @@ class TestGetElementsByMaterial(NewFile): def test_run(self): ifc = ifcopenshell.file() tool.Ifc.set(ifc) - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - material = ifcopenshell.api.run("material.add_material", ifc) - ifcopenshell.api.run("material.assign_material", ifc, products=[element], material=material) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + material = ifcopenshell.api.material.add_material(ifc) + ifcopenshell.api.material.assign_material(ifc, products=[element], material=material) assert subject.get_elements_by_material(material) == {element} diff --git a/src/bonsai/test/tool/test_misc.py b/src/bonsai/test/tool/test_misc.py index 2091d6e3d7..883755888a 100644 --- a/src/bonsai/test/tool/test_misc.py +++ b/src/bonsai/test/tool/test_misc.py @@ -20,6 +20,9 @@ import bpy import math import numpy import ifcopenshell +import ifcopenshell.api.aggregate +import ifcopenshell.api.spatial +import ifcopenshell.api.unit import test.bim.bootstrap import bonsai.core.tool import bonsai.tool as tool @@ -39,7 +42,7 @@ class TestGetObjectStorey(test.bim.bootstrap.NewFile): wall = ifc.createIfcWall() tool.Ifc.link(wall, obj) storey = ifc.createIfcBuildingStorey() - ifcopenshell.api.run("spatial.assign_container", ifc, products=[wall], relating_structure=storey) + ifcopenshell.api.spatial.assign_container(ifc, products=[wall], relating_structure=storey) assert subject.get_object_storey(obj) == storey def test_only_returning_a_building_storey(self): @@ -49,7 +52,7 @@ class TestGetObjectStorey(test.bim.bootstrap.NewFile): wall = ifc.createIfcWall() tool.Ifc.link(wall, obj) building = ifc.createIfcBuilding() - ifcopenshell.api.run("spatial.assign_container", ifc, products=[wall], relating_structure=building) + ifcopenshell.api.spatial.assign_container(ifc, products=[wall], relating_structure=building) assert subject.get_object_storey(obj) is None def test_returning_nothing_if_uncontained(self): @@ -65,8 +68,8 @@ class TestGetStoreyElevation(test.bim.bootstrap.NewFile): def test_run(self): ifc = ifcopenshell.file() ifc.createIfcProject() - unit = ifcopenshell.api.run("unit.add_si_unit", ifc, prefix="MILLI") - ifcopenshell.api.run("unit.assign_unit", ifc, units=[unit]) + unit = ifcopenshell.api.unit.add_si_unit(ifc, prefix="MILLI") + ifcopenshell.api.unit.assign_unit(ifc, units=[unit]) storey = ifc.createIfcBuildingStorey() storey.Elevation = 3000 tool.Ifc.set(ifc) @@ -77,23 +80,23 @@ class TestGetStoreyHeight(test.bim.bootstrap.NewFile): def test_run(self): ifc = ifcopenshell.file() ifc.createIfcProject() - unit = ifcopenshell.api.run("unit.add_si_unit", ifc, prefix="MILLI") - ifcopenshell.api.run("unit.assign_unit", ifc, units=[unit]) + unit = ifcopenshell.api.unit.add_si_unit(ifc, prefix="MILLI") + ifcopenshell.api.unit.assign_unit(ifc, units=[unit]) tool.Ifc.set(ifc) building = ifc.createIfcBuilding() storey = ifc.createIfcBuildingStorey() storey.Elevation = 3000 storey2 = ifc.createIfcBuildingStorey() storey2.Elevation = 5000 - ifcopenshell.api.run("aggregate.assign_object", ifc, products=[storey], relating_object=building) - ifcopenshell.api.run("aggregate.assign_object", ifc, products=[storey2], relating_object=building) + ifcopenshell.api.aggregate.assign_object(ifc, products=[storey], relating_object=building) + ifcopenshell.api.aggregate.assign_object(ifc, products=[storey2], relating_object=building) assert subject.get_storey_height_in_si(storey, 1) == 2.0 def test_getting_a_double_storey_height(self): ifc = ifcopenshell.file() ifc.createIfcProject() - unit = ifcopenshell.api.run("unit.add_si_unit", ifc, prefix="MILLI") - ifcopenshell.api.run("unit.assign_unit", ifc, units=[unit]) + unit = ifcopenshell.api.unit.add_si_unit(ifc, prefix="MILLI") + ifcopenshell.api.unit.assign_unit(ifc, units=[unit]) tool.Ifc.set(ifc) building = ifc.createIfcBuilding() storey = ifc.createIfcBuildingStorey() @@ -102,9 +105,9 @@ class TestGetStoreyHeight(test.bim.bootstrap.NewFile): storey2.Elevation = 5000 storey3 = ifc.createIfcBuildingStorey() storey3.Elevation = 9000 - ifcopenshell.api.run("aggregate.assign_object", ifc, products=[storey], relating_object=building) - ifcopenshell.api.run("aggregate.assign_object", ifc, products=[storey2], relating_object=building) - ifcopenshell.api.run("aggregate.assign_object", ifc, products=[storey3], relating_object=building) + ifcopenshell.api.aggregate.assign_object(ifc, products=[storey], relating_object=building) + ifcopenshell.api.aggregate.assign_object(ifc, products=[storey2], relating_object=building) + ifcopenshell.api.aggregate.assign_object(ifc, products=[storey3], relating_object=building) assert subject.get_storey_height_in_si(storey, 2) == 6.0 def test_only_considering_storeys_in_the_same_building(self): @@ -115,7 +118,7 @@ class TestGetStoreyHeight(test.bim.bootstrap.NewFile): storey.Elevation = 3000 storey2 = ifc.createIfcBuildingStorey() storey2.Elevation = 5000 - ifcopenshell.api.run("aggregate.assign_object", ifc, products=[storey], relating_object=building) + ifcopenshell.api.aggregate.assign_object(ifc, products=[storey], relating_object=building) assert subject.get_storey_height_in_si(storey, 1) is None def test_returning_none_if_the_storey_height_is_undefined(self): @@ -123,7 +126,7 @@ class TestGetStoreyHeight(test.bim.bootstrap.NewFile): tool.Ifc.set(ifc) building = ifc.createIfcBuilding() storey = ifc.createIfcBuildingStorey() - ifcopenshell.api.run("aggregate.assign_object", ifc, products=[storey], relating_object=building) + ifcopenshell.api.aggregate.assign_object(ifc, products=[storey], relating_object=building) assert subject.get_storey_height_in_si(storey, 1) is None diff --git a/src/bonsai/test/tool/test_model.py b/src/bonsai/test/tool/test_model.py index 20571dbb18..4b0182b5ad 100644 --- a/src/bonsai/test/tool/test_model.py +++ b/src/bonsai/test/tool/test_model.py @@ -18,13 +18,14 @@ import bpy import ifcopenshell +import ifcopenshell.api.geometry import ifcopenshell.api.material import ifcopenshell.api.root import ifcopenshell.api.style import ifcopenshell.api.type import ifcopenshell.util.element import ifcopenshell.util.representation -import ifcopenshell.util.unit +import ifcopenshell.util.shape_builder import bonsai.core.tool import bonsai.tool as tool import numpy as np diff --git a/src/bonsai/test/tool/test_nest.py b/src/bonsai/test/tool/test_nest.py index c9499e40de..257bbcee88 100644 --- a/src/bonsai/test/tool/test_nest.py +++ b/src/bonsai/test/tool/test_nest.py @@ -18,6 +18,8 @@ import bpy import ifcopenshell +import ifcopenshell.api +import ifcopenshell.api.spatial import bonsai.core.tool import bonsai.tool as tool from test.bim.bootstrap import NewFile @@ -72,5 +74,5 @@ class TestGetContainer(NewFile): tool.Ifc.set(ifc) element = ifc.createIfcWall() container = ifc.createIfcBuildingStorey() - ifcopenshell.api.run("spatial.assign_container", ifc, products=[element], relating_structure=container) + ifcopenshell.api.spatial.assign_container(ifc, products=[element], relating_structure=container) assert subject.get_container(element) == container diff --git a/src/bonsai/test/tool/test_patch.py b/src/bonsai/test/tool/test_patch.py index 48c0e16af5..8fce8974a9 100644 --- a/src/bonsai/test/tool/test_patch.py +++ b/src/bonsai/test/tool/test_patch.py @@ -36,5 +36,6 @@ class TestRunMigratePatch(NewFile): infile = os.path.join(cwd, "..", "files", "ifc2x3.ifc") outfile = os.path.join(cwd, "..", "files", "temp", "ifc2x3-migrated.ifc") subject.run_migrate_patch(infile, outfile, "IFC4") + ifc: ifcopenshell.file ifc = ifcopenshell.open(outfile) assert ifc.schema == "IFC4" diff --git a/src/bonsai/test/tool/test_project.py b/src/bonsai/test/tool/test_project.py index a87b00f753..e8cbf294b9 100644 --- a/src/bonsai/test/tool/test_project.py +++ b/src/bonsai/test/tool/test_project.py @@ -18,8 +18,10 @@ import bpy import ifcopenshell +import ifcopenshell.api.context import ifcopenshell.api.document import ifcopenshell.api.root +import ifcopenshell.api.unit import bonsai.core.tool import bonsai.tool as tool import tempfile @@ -106,9 +108,8 @@ class TestSetDefaultContext(NewFile): ifc = ifcopenshell.file() tool.Ifc.set(ifc) ifc.createIfcProject() - model = ifcopenshell.api.run("context.add_context", ifc, context_type="Model") - body = ifcopenshell.api.run( - "context.add_context", + model = ifcopenshell.api.context.add_context(ifc, context_type="Model") + body = ifcopenshell.api.context.add_context( ifc, parent=model, context_type="Model", @@ -125,7 +126,7 @@ class TestSetDefaultModelingDimensions(NewFile): ifc = ifcopenshell.file() tool.Ifc.set(ifc) ifc.createIfcProject() - ifcopenshell.api.run("unit.assign_unit", ifc) + ifcopenshell.api.unit.assign_unit(ifc) subject.set_default_modeling_dimensions() props = tool.Model.get_model_props() assert props.extrusion_depth == 3 diff --git a/src/bonsai/test/tool/test_pset.py b/src/bonsai/test/tool/test_pset.py index b12c46f0ef..9aa8e70289 100644 --- a/src/bonsai/test/tool/test_pset.py +++ b/src/bonsai/test/tool/test_pset.py @@ -18,6 +18,8 @@ import bpy import ifcopenshell +import ifcopenshell.api +import ifcopenshell.api.pset import bonsai.core.tool import bonsai.tool as tool from bonsai.tool.pset import Pset as subject @@ -34,7 +36,7 @@ class TestGetElementPset(NewFile): ifc = ifcopenshell.file() tool.Ifc.set(ifc) element = ifc.createIfcWall() - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo") + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="Foo") assert subject.get_element_pset(element, "Foo") == pset @@ -43,9 +45,9 @@ class TestIsPsetEmpty(NewFile): ifc = ifcopenshell.file() tool.Ifc.set(ifc) element = ifc.createIfcWall() - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo") + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="Foo") assert subject.is_pset_empty(pset) is True - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": "Bar"}) assert subject.is_pset_empty(pset) is False - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": None}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": None}) assert subject.is_pset_empty(pset) is True diff --git a/src/bonsai/test/tool/test_qto.py b/src/bonsai/test/tool/test_qto.py index 7ab26cd9d8..2b06cbb3c9 100644 --- a/src/bonsai/test/tool/test_qto.py +++ b/src/bonsai/test/tool/test_qto.py @@ -19,6 +19,11 @@ import bpy import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.context +import ifcopenshell.api.cost +import ifcopenshell.api.pset +import ifcopenshell.api.root +import ifcopenshell.api.unit import ifcopenshell.util.pset import test.bim.bootstrap import bonsai.core.tool @@ -58,7 +63,7 @@ class TestGetCalculatedObjectQuantities(test.bim.bootstrap.NewFile): self.ifc = ifcopenshell.file() tool.Ifc.set(self.ifc) - ifcopenshell.api.run("root.create_entity", self.ifc, ifc_class="IfcProject", name="My Project") + ifcopenshell.api.root.create_entity(self.ifc, ifc_class="IfcProject", name="My Project") ifc_import_settings = import_ifc.IfcImportSettings.factory( bpy.context, tool.Ifc.get_path(), logging.getLogger("ImportIFC") ) @@ -67,12 +72,12 @@ class TestGetCalculatedObjectQuantities(test.bim.bootstrap.NewFile): ifc_importer.create_project() def setup_units(self, units): - ifcopenshell.api.run("unit.assign_unit", self.ifc, **units) + ifcopenshell.api.unit.assign_unit(self.ifc, **units) def calculate_quantities(self, obj): import ifc5d.qto - context = ifcopenshell.api.run("context.add_context", self.ifc, context_type="Model") + context = ifcopenshell.api.context.add_context(self.ifc, context_type="Model") bpy.ops.mesh.primitive_cube_add(location=(0.0, 0.0, 0.0), size=2) obj = bpy.context.active_object element = bonsai.core.root.assign_class( @@ -183,7 +188,7 @@ class TestGetBaseQto(test.bim.bootstrap.NewFile): wall_obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh")) tool.Ifc.link(wall, wall_obj) product = tool.Ifc.get_entity(wall_obj) - pset_qto = ifcopenshell.api.run("pset.add_qto", ifc, product=wall, name="Qto_Basefoo") + pset_qto = ifcopenshell.api.pset.add_qto(ifc, product=wall, name="Qto_Basefoo") assert subject.get_base_qto(product).id() == pset_qto.get_info()["id"] assert subject.get_base_qto(product).Name == pset_qto.Name @@ -202,14 +207,12 @@ class TestGetRelatedCostItemQuantities(test.bim.bootstrap.NewFile): ifc = ifcopenshell.file() tool.Ifc.set(ifc) wall = ifc.createIfcWall() - schedule = ifcopenshell.api.run("cost.add_cost_schedule", ifc) - item = ifcopenshell.api.run("cost.add_cost_item", ifc, cost_schedule=schedule) - ifcopenshell.api.run("cost.edit_cost_item", ifc, cost_item=item, attributes={"Name": "Foo"}) - qto = ifcopenshell.api.run("pset.add_qto", ifc, product=wall, name="Qto_WallBaseQuantities") - ifcopenshell.api.run("pset.edit_qto", ifc, qto=qto, properties={"NetVolume": 42.0}) - ifcopenshell.api.run( - "cost.assign_cost_item_quantity", ifc, cost_item=item, products=[wall], prop_name="NetVolume" - ) + schedule = ifcopenshell.api.cost.add_cost_schedule(ifc) + item = ifcopenshell.api.cost.add_cost_item(ifc, cost_schedule=schedule) + ifcopenshell.api.cost.edit_cost_item(ifc, cost_item=item, attributes={"Name": "Foo"}) + qto = ifcopenshell.api.pset.add_qto(ifc, product=wall, name="Qto_WallBaseQuantities") + ifcopenshell.api.pset.edit_qto(ifc, qto=qto, properties={"NetVolume": 42.0}) + ifcopenshell.api.cost.assign_cost_item_quantity(ifc, cost_item=item, products=[wall], prop_name="NetVolume") assert subject.get_related_cost_item_quantities(wall)[0]["cost_item_name"] == "Foo" assert subject.get_related_cost_item_quantities(wall)[0]["quantity_name"] == "NetVolume" assert subject.get_related_cost_item_quantities(wall)[0]["quantity_value"] == 42 diff --git a/src/bonsai/test/tool/test_root.py b/src/bonsai/test/tool/test_root.py index 5b3e132be2..73031d1d36 100644 --- a/src/bonsai/test/tool/test_root.py +++ b/src/bonsai/test/tool/test_root.py @@ -19,6 +19,8 @@ import bpy import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.feature +import ifcopenshell.api.type import bonsai.core.tool import bonsai.tool as tool from test.bim.bootstrap import NewFile @@ -74,8 +76,8 @@ class TestGetDecompositionRelationships(NewFile): element = ifc.createIfcWall() opening = ifc.createIfcOpeningElement() fill = ifc.createIfcWindow() - ifcopenshell.api.run("feature.add_feature", ifc, feature=opening, element=element) - ifcopenshell.api.run("feature.add_filling", ifc, opening=opening, element=fill) + ifcopenshell.api.feature.add_feature(ifc, feature=opening, element=element) + ifcopenshell.api.feature.add_filling(ifc, opening=opening, element=fill) obj = bpy.data.objects.new("Object", None) tool.Ifc.link(fill, obj) @@ -99,7 +101,7 @@ class TestGetElementType(NewFile): ifc = tool.Ifc.get() element = ifc.createIfcWall() type = ifc.createIfcWallType() - ifcopenshell.api.run("type.assign_type", ifc, related_objects=[element], relating_type=type) + ifcopenshell.api.type.assign_type(ifc, related_objects=[element], relating_type=type) assert subject.get_element_type(element) == type diff --git a/src/bonsai/test/tool/test_spatial.py b/src/bonsai/test/tool/test_spatial.py index 9bcc84c6dc..fd9316912a 100644 --- a/src/bonsai/test/tool/test_spatial.py +++ b/src/bonsai/test/tool/test_spatial.py @@ -20,6 +20,8 @@ import numpy as np import bpy import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.root +import ifcopenshell.api.spatial import bonsai.core.tool import bonsai.tool as tool from bonsai.tool.spatial import Spatial as subject @@ -158,7 +160,7 @@ class TestGetContainer(NewFile): ifc = ifcopenshell.file() site = ifc.createIfcSite() wall = ifc.createIfcWall() - ifcopenshell.api.run("spatial.assign_container", ifc, products=[wall], relating_structure=site) + ifcopenshell.api.spatial.assign_container(ifc, products=[wall], relating_structure=site) assert subject.get_container(wall) == site @@ -167,7 +169,7 @@ class TestGetDecomposedElements(NewFile): ifc = ifcopenshell.file() site = ifc.createIfcSite() wall = ifc.createIfcWall() - ifcopenshell.api.run("spatial.assign_container", ifc, products=[wall], relating_structure=site) + ifcopenshell.api.spatial.assign_container(ifc, products=[wall], relating_structure=site) assert subject.get_decomposed_elements(site) == {wall} @@ -227,7 +229,7 @@ class TestSelectProducts(NewFile): def test_select_products(self): ifc = ifcopenshell.file() tool.Ifc.set(ifc) - product = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") + product = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") obj = bpy.data.objects.new("Object", None) bpy.context.scene.collection.objects.link(obj) tool.Ifc.link(product, obj) @@ -240,7 +242,7 @@ class TestGenerateSpace(NewFile): bpy.ops.bim.create_project() ifc = tool.Ifc.get() scene = bpy.context.scene - product = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") + product = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") bpy.ops.mesh.primitive_cube_add(size=10, location=(0, 0, 4)) obj = bpy.data.objects["Cube"] scene.collection.objects.link(obj) diff --git a/src/bonsai/test/tool/test_style.py b/src/bonsai/test/tool/test_style.py index ba72c3b5e4..c77c71d5c8 100644 --- a/src/bonsai/test/tool/test_style.py +++ b/src/bonsai/test/tool/test_style.py @@ -20,6 +20,7 @@ import os import bpy import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.root import ifcopenshell.util.representation import bonsai.core.tool import bonsai.tool as tool @@ -105,7 +106,7 @@ class TestGetElementsByStyle(NewFile): def test_run(self): ifc = ifcopenshell.file() tool.Ifc.set(ifc) - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") style = ifc.createIfcSurfaceStyle() item = ifc.createIfcExtrudedAreaSolid() ifc.createIfcStyledItem(Item=item, Styles=[style]) diff --git a/src/bonsai/test/tool/test_surveyor.py b/src/bonsai/test/tool/test_surveyor.py index 5d3684fdcf..0228cd9271 100644 --- a/src/bonsai/test/tool/test_surveyor.py +++ b/src/bonsai/test/tool/test_surveyor.py @@ -20,6 +20,8 @@ import bpy import numpy as np import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.root +import ifcopenshell.api.unit import ifcopenshell.util.geolocation import test.bim.bootstrap @@ -42,9 +44,9 @@ class TestGetGlobalMatrix(test.bim.bootstrap.NewFile): def test_applying_an_object_placement_blender_offset(self): ifc = ifcopenshell.file() - ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") - unit = ifcopenshell.api.run("unit.add_si_unit", ifc, unit_type="LENGTHUNIT", prefix="MILLI") - ifcopenshell.api.run("unit.assign_unit", ifc, units=[unit]) + ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcProject") + unit = ifcopenshell.api.unit.add_si_unit(ifc, unit_type="LENGTHUNIT", prefix="MILLI") + ifcopenshell.api.unit.assign_unit(ifc, units=[unit]) tool.Ifc.set(ifc) props = tool.Georeference.get_georeference_props() props.has_blender_offset = True diff --git a/src/bonsai/test/tool/test_system.py b/src/bonsai/test/tool/test_system.py index 5ed7eab16d..de8e9026b0 100644 --- a/src/bonsai/test/tool/test_system.py +++ b/src/bonsai/test/tool/test_system.py @@ -19,6 +19,8 @@ import bpy import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.root +import ifcopenshell.api.system import ifcopenshell.util.unit import bonsai.core.tool import bonsai.tool as tool @@ -150,9 +152,9 @@ class TestExportSystemAttributes(NewFile): class TestGetConnectedPort(NewFile): def test_run(self): ifc = ifcopenshell.file() - port1 = ifcopenshell.api.run("system.add_port", ifc) - port2 = ifcopenshell.api.run("system.add_port", ifc) - ifcopenshell.api.run("system.connect_port", ifc, port1=port1, port2=port2) + port1 = ifcopenshell.api.system.add_port(ifc) + port2 = ifcopenshell.api.system.add_port(ifc) + ifcopenshell.api.system.connect_port(ifc, port1=port1, port2=port2) assert subject.get_connected_port(port1) == port2 assert subject.get_connected_port(port2) == port1 @@ -163,7 +165,7 @@ class TestGetPorts(NewFile): tool.Ifc().set(ifc) element = ifc.createIfcDuctSegment() port = ifc.createIfcDistributionPort() - ifcopenshell.api.run("system.assign_port", ifc, element=element, port=port) + ifcopenshell.api.system.assign_port(ifc, element=element, port=port) assert subject.get_ports(element) == [port] @@ -268,9 +270,9 @@ class TestSelectSystemProducts(NewFile): assert bpy.context.scene ifc = ifcopenshell.file() tool.Ifc().set(ifc) - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcPump") - system = ifcopenshell.api.run("system.add_system", ifc, ifc_class="IfcSystem") - ifcopenshell.api.run("system.assign_system", ifc, products=[element], system=system) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcPump") + system = ifcopenshell.api.system.add_system(ifc, ifc_class="IfcSystem") + ifcopenshell.api.system.assign_system(ifc, products=[element], system=system) obj = bpy.data.objects.new("Object", None) bpy.context.scene.collection.objects.link(obj) tool.Ifc.link(element, obj) @@ -282,7 +284,7 @@ class TestSetActiveSystem(NewFile): def test_run(self): ifc = ifcopenshell.file() tool.Ifc().set(ifc) - system = ifcopenshell.api.run("system.add_system", ifc, ifc_class="IfcSystem") + system = ifcopenshell.api.system.add_system(ifc, ifc_class="IfcSystem") subject.set_active_edited_system(system) props = tool.System.get_system_props() assert props.edited_system_id == system.id() @@ -298,14 +300,12 @@ class TestFlowElementAndControls(NewFile): assert len(subject.get_flow_element_controls(flow_element)) == 0 assert subject.get_flow_control_flow_element(flow_control) == None - ifcopenshell.api.run( - "system.assign_flow_control", + ifcopenshell.api.system.assign_flow_control( ifc, related_flow_control=flow_control, relating_flow_element=flow_element, ) - ifcopenshell.api.run( - "system.assign_flow_control", + ifcopenshell.api.system.assign_flow_control( ifc, related_flow_control=flow_control1, relating_flow_element=flow_element, diff --git a/src/bonsai/test/tool/test_type.py b/src/bonsai/test/tool/test_type.py index 04614986ea..5bbf3c4c42 100644 --- a/src/bonsai/test/tool/test_type.py +++ b/src/bonsai/test/tool/test_type.py @@ -122,7 +122,7 @@ class TestGetModelTypes(NewFile): ifc = ifcopenshell.file() tool.Ifc.set(ifc) type_classes = ("IfcWallType", "IfcDoorStyle", "IfcWindowStyle", "IfcTypeProduct") - types = [ifcopenshell.api.run("root.create_entity", ifc, ifc_class=c) for c in type_classes] + types = [ifcopenshell.api.root.create_entity(ifc, ifc_class=c) for c in type_classes] assert set(subject.get_model_types()) == set(types) diff --git a/src/bsdd/bsdd.py b/src/bsdd/bsdd.py index 9292008439..9a24d1dd1e 100644 --- a/src/bsdd/bsdd.py +++ b/src/bsdd/bsdd.py @@ -23,10 +23,13 @@ import urllib.parse import requests import webbrowser import http.server -from typing import TypedDict, Literal, Optional +from typing import TypedDict, Literal, Optional, TYPE_CHECKING, Any from typing_extensions import NotRequired +if TYPE_CHECKING: + import ifcopenshell + __version__ = version = "0.0.0" Status = Literal["Preview", "Active", "Inactive"] @@ -858,8 +861,11 @@ class Client: return self.get(endpoint, params) -def apply_ifc_classification_properties(ifc_file, element, classificationProperties): +def apply_ifc_classification_properties( + ifc_file: ifcopenshell.file, element: ifcopenshell.entity_instance, classificationProperties: dict[str, Any] +) -> None: import ifcopenshell.api + import ifcopenshell.api.pset import ifcopenshell.util.element psets = ifcopenshell.util.element.get_psets(element) @@ -871,7 +877,7 @@ def apply_ifc_classification_properties(ifc_file, element, classificationPropert if pset: pset = ifc_file.by_id(pset["id"]) else: - pset = ifcopenshell.api.run("pset.add_pset", ifc_file, product=element, name=prop["propertySet"]) + pset = ifcopenshell.api.pset.add_pset(ifc_file, product=element, name=prop["propertySet"]) if prop["dataType"] == "boolean": predefinedValue = predefinedValue == "TRUE" - ifcopenshell.api.run("pset.edit_pset", ifc_file, pset=pset, properties={prop["name"]: predefinedValue}) + ifcopenshell.api.pset.edit_pset(ifc_file, pset=pset, properties={prop["name"]: predefinedValue}) diff --git a/src/ifc4d/ifc4d/common.py b/src/ifc4d/ifc4d/common.py index e433ba9363..e54f350ed5 100644 --- a/src/ifc4d/ifc4d/common.py +++ b/src/ifc4d/ifc4d/common.py @@ -1,6 +1,9 @@ from __future__ import annotations import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.control +import ifcopenshell.api.resource +import ifcopenshell.api.sequence import ifcopenshell.util.date from datetime import datetime, timedelta, date from typing import Union, Any, TypedDict @@ -81,7 +84,7 @@ class ScheduleIfcGenerator: if not self.file: self.file = self.create_boilerplate_ifc() if not self.work_plan: - self.work_plan = ifcopenshell.api.run("sequence.add_work_plan", self.file) + self.work_plan = ifcopenshell.api.sequence.add_work_plan(self.file) work_schedule = self.create_work_schedule() self.create_calendars() self.create_tasks(work_schedule) @@ -91,13 +94,13 @@ class ScheduleIfcGenerator: self.file.write(self.output) def create_work_schedule(self) -> ifcopenshell.entity_instance: - return ifcopenshell.api.run( - "sequence.add_work_schedule", self.file, name=self.project["Name"], work_plan=self.work_plan + return ifcopenshell.api.sequence.add_work_schedule( + self.file, name=self.project["Name"], work_plan=self.work_plan ) def create_calendars(self) -> None: for calendar_id, calendar in self.calendars.items(): - calendar["ifc"] = ifcopenshell.api.run("sequence.add_work_calendar", self.file, name=calendar["Name"]) + calendar["ifc"] = ifcopenshell.api.sequence.add_work_calendar(self.file, name=calendar["Name"]) calendar["ifc"].Identification = str(calendar_id) self.process_working_week(calendar["StandardWorkWeek"], calendar["ifc"]) self.process_exceptions(calendar.get("HolidayOrExceptions"), calendar["ifc"]) @@ -107,8 +110,8 @@ class ScheduleIfcGenerator: if day["ifc"] or not day.get("WorkTimes"): continue - day["ifc"] = ifcopenshell.api.run( - "sequence.add_work_time", self.file, work_calendar=calendar, time_type="WorkingTimes" + day["ifc"] = ifcopenshell.api.sequence.add_work_time( + self.file, work_calendar=calendar, time_type="WorkingTimes" ) weekday_component = [self.day_map[day["DayOfWeek"]]] for day2 in week: @@ -120,25 +123,22 @@ class ScheduleIfcGenerator: day2["ifc"] = day["ifc"] work_time_name = "Weekdays: {}".format(", ".join([str(c) for c in sorted(weekday_component)])) - ifcopenshell.api.run( - "sequence.edit_work_time", + ifcopenshell.api.sequence.edit_work_time( self.file, work_time=day["ifc"], attributes={"Name": work_time_name}, ) - recurrence = ifcopenshell.api.run( - "sequence.assign_recurrence_pattern", self.file, parent=day["ifc"], recurrence_type="WEEKLY" + recurrence = ifcopenshell.api.sequence.assign_recurrence_pattern( + self.file, parent=day["ifc"], recurrence_type="WEEKLY" ) - ifcopenshell.api.run( - "sequence.edit_recurrence_pattern", + ifcopenshell.api.sequence.edit_recurrence_pattern( self.file, recurrence_pattern=recurrence, attributes={"WeekdayComponent": weekday_component}, ) for work_time in day["WorkTimes"]: - ifcopenshell.api.run( - "sequence.add_time_period", + ifcopenshell.api.sequence.add_time_period( self.file, recurrence_pattern=recurrence, start_time=work_time["Start"], @@ -159,11 +159,10 @@ class ScheduleIfcGenerator: def process_full_day_exceptions( self, year: int, month: int, month_data: dict[str, Any], calendar: ifcopenshell.entity_instance ): - work_time = ifcopenshell.api.run( - "sequence.add_work_time", self.file, work_calendar=calendar, time_type="ExceptionTimes" + work_time = ifcopenshell.api.sequence.add_work_time( + self.file, work_calendar=calendar, time_type="ExceptionTimes" ) - ifcopenshell.api.run( - "sequence.edit_work_time", + ifcopenshell.api.sequence.edit_work_time( self.file, work_time=work_time, attributes={ @@ -172,14 +171,12 @@ class ScheduleIfcGenerator: "Finish": date(year, 12, 31), }, ) - recurrence = ifcopenshell.api.run( - "sequence.assign_recurrence_pattern", + recurrence = ifcopenshell.api.sequence.assign_recurrence_pattern( self.file, parent=work_time, recurrence_type="YEARLY_BY_DAY_OF_MONTH", ) - ifcopenshell.api.run( - "sequence.edit_recurrence_pattern", + ifcopenshell.api.sequence.edit_recurrence_pattern( self.file, recurrence_pattern=recurrence, attributes={"DayComponent": month_data["FullDay"], "MonthComponent": [month]}, @@ -192,8 +189,8 @@ class ScheduleIfcGenerator: if day["ifc"]: continue - day["ifc"] = ifcopenshell.api.run( - "sequence.add_work_time", self.file, work_calendar=calendar, time_type="ExceptionTimes" + day["ifc"] = ifcopenshell.api.sequence.add_work_time( + self.file, work_calendar=calendar, time_type="ExceptionTimes" ) day_component = [day["Day"]] @@ -205,8 +202,7 @@ class ScheduleIfcGenerator: # Don't process the next day, as we can group it day2["ifc"] = day["ifc"] - ifcopenshell.api.run( - "sequence.edit_work_time", + ifcopenshell.api.sequence.edit_work_time( self.file, work_time=day["ifc"], attributes={ @@ -215,21 +211,18 @@ class ScheduleIfcGenerator: "Finish": date(year, 12, 31), }, ) - recurrence = ifcopenshell.api.run( - "sequence.assign_recurrence_pattern", + recurrence = ifcopenshell.api.sequence.assign_recurrence_pattern( self.file, parent=day["ifc"], recurrence_type="YEARLY_BY_DAY_OF_MONTH", ) - ifcopenshell.api.run( - "sequence.edit_recurrence_pattern", + ifcopenshell.api.sequence.edit_recurrence_pattern( self.file, recurrence_pattern=recurrence, attributes={"DayComponent": day_component, "MonthComponent": [month]}, ) for work_time in day["WorkTimes"]: - ifcopenshell.api.run( - "sequence.add_time_period", + ifcopenshell.api.sequence.add_time_period( self.file, recurrence_pattern=recurrence, start_time=work_time["Start"], @@ -245,8 +238,7 @@ class ScheduleIfcGenerator: def create_task_from_wbs(self, wbs: WBSEntry, work_schedule: ifcopenshell.entity_instance) -> None: if not self.wbs.get(wbs["ParentObjectId"]): wbs["ParentObjectId"] = None - wbs["ifc"] = ifcopenshell.api.run( - "sequence.add_task", + wbs["ifc"] = ifcopenshell.api.sequence.add_task( self.file, work_schedule=None if wbs["ParentObjectId"] else work_schedule, parent_task=self.wbs[wbs["ParentObjectId"]]["ifc"] if wbs["ParentObjectId"] else None, @@ -255,8 +247,7 @@ class ScheduleIfcGenerator: if wbs["ParentObjectId"]: if self.wbs[wbs["ParentObjectId"]]["ifc"]: identification = str(self.wbs[wbs["ParentObjectId"]]["ifc"].Identification) + "." + str(wbs["Code"]) - ifcopenshell.api.run( - "sequence.edit_task", + ifcopenshell.api.sequence.edit_task( self.file, task=wbs["ifc"], attributes={"Name": wbs["Name"], "Identification": str(identification)}, @@ -270,14 +261,12 @@ class ScheduleIfcGenerator: wbs: Union[WBSEntry, None], work_schedule: Union[ifcopenshell.entity_instance, None], ) -> None: - activity["ifc"] = ifcopenshell.api.run( - "sequence.add_task", + activity["ifc"] = ifcopenshell.api.sequence.add_task( self.file, work_schedule=None if wbs else work_schedule, parent_task=wbs["ifc"] if wbs else None, ) - ifcopenshell.api.run( - "sequence.edit_task", + ifcopenshell.api.sequence.edit_task( self.file, task=activity["ifc"], attributes={ @@ -288,19 +277,17 @@ class ScheduleIfcGenerator: "PredefinedType": "CONSTRUCTION", }, ) - task_time = ifcopenshell.api.run("sequence.add_task_time", self.file, task=activity["ifc"]) + task_time = ifcopenshell.api.sequence.add_task_time(self.file, task=activity["ifc"]) calendar = self.calendars[activity["CalendarObjectId"]] # Seems intermittently crashy - can we investigate for larger files? - ifcopenshell.api.run( - "control.assign_control", + ifcopenshell.api.control.assign_control( self.file, **{ "relating_control": calendar["ifc"], "related_object": activity["ifc"], }, ) - ifcopenshell.api.run( - "sequence.edit_task_time", + ifcopenshell.api.sequence.edit_task_time( self.file, task_time=task_time, attributes={ @@ -323,14 +310,12 @@ class ScheduleIfcGenerator: "Finish to Finish": "FINISH_FINISH", } for relationship in self.relationships.values(): - rel_sequence = ifcopenshell.api.run( - "sequence.assign_sequence", + rel_sequence = ifcopenshell.api.sequence.assign_sequence( self.file, relating_process=self.activities[relationship["PredecessorActivity"]]["ifc"], related_process=self.activities[relationship["SuccessorActivity"]]["ifc"], ) - ifcopenshell.api.run( - "sequence.edit_sequence", + ifcopenshell.api.sequence.edit_sequence( self.file, rel_sequence=rel_sequence, attributes={"SequenceType": relationship["Type"]}, @@ -338,8 +323,7 @@ class ScheduleIfcGenerator: lag = float(relationship["Lag"]) if lag: calendar = self.calendars[self.activities[relationship["PredecessorActivity"]]["CalendarObjectId"]] - ifcopenshell.api.run( - "sequence.assign_lag_time", + ifcopenshell.api.sequence.assign_lag_time( self.file, rel_sequence=rel_sequence, lag_value=timedelta(days=lag / float(calendar["HoursPerDay"] or 8)), @@ -353,14 +337,12 @@ class ScheduleIfcGenerator: parent = self.resources.get(resource.get("ParentObjectId")) if parent: if not parent.get("ifc"): - parent["ifc"] = ifcopenshell.api.run( - "resource.add_resource", + parent["ifc"] = ifcopenshell.api.resource.add_resource( self.file, **{"ifc_class": "IfcCrewResource", "name": parent["Name"]}, ) if parent: - resource["ifc"] = ifcopenshell.api.run( - "resource.add_resource", + resource["ifc"] = ifcopenshell.api.resource.add_resource( self.file, **{ "parent_resource": parent["ifc"] if parent else None, @@ -369,8 +351,8 @@ class ScheduleIfcGenerator: }, ) else: - resource["ifc"] = ifcopenshell.api.run( - "resource.add_resource", self.file, **{"ifc_class": "IfcCrewResource", "name": resource["Name"]} + resource["ifc"] = ifcopenshell.api.resource.add_resource( + self.file, **{"ifc_class": "IfcCrewResource", "name": resource["Name"]} ) def create_boilerplate_ifc(self) -> None: diff --git a/src/ifc4d/ifc4d/csv2ifc.py b/src/ifc4d/ifc4d/csv2ifc.py index 6d18e13a6e..1233734290 100644 --- a/src/ifc4d/ifc4d/csv2ifc.py +++ b/src/ifc4d/ifc4d/csv2ifc.py @@ -23,6 +23,10 @@ import ifcopenshell.api.resource import isodate import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.cost +import ifcopenshell.api.pset +import ifcopenshell.api.root +import ifcopenshell.api.unit import ifcopenshell.util.date import ifcopenshell.util.element import ifcopenshell.util.resource @@ -186,24 +190,23 @@ class Csv2Ifc: def create_resource(self, resource: dict[str, Any], parent: Union[ifcopenshell.entity_instance, None]) -> None: assert self.file if parent is None: - resource["ifc"] = ifcopenshell.api.run("resource.add_resource", self.file, ifc_class=resource["class"]) + resource["ifc"] = ifcopenshell.api.resource.add_resource(self.file, ifc_class=resource["class"]) else: - resource["ifc"] = ifcopenshell.api.run( - "resource.add_resource", self.file, parent_resource=parent, ifc_class=resource["class"] + resource["ifc"] = ifcopenshell.api.resource.add_resource( + self.file, parent_resource=parent, ifc_class=resource["class"] ) resource["ifc"].Name = resource["Name"] if resource.get("Description", None): resource["ifc"].Description = resource.get("Description") if resource["Productivity"]: - pset = ifcopenshell.api.run("pset.add_pset", self.file, product=resource["ifc"], name="EPset_Productivity") - ifcopenshell.api.run( - "pset.edit_pset", + pset = ifcopenshell.api.pset.add_pset(self.file, product=resource["ifc"], name="EPset_Productivity") + ifcopenshell.api.pset.edit_pset( self.file, pset=pset, properties=resource["Productivity"], ) if resource["BaseCostValue"]: - cost_value = ifcopenshell.api.run("cost.add_cost_value", self.file, parent=resource["ifc"]) + cost_value = ifcopenshell.api.cost.add_cost_value(self.file, parent=resource["ifc"]) cost_value.AppliedValue = self.file.createIfcMonetaryMeasure(resource["BaseCostValue"]) if usage_value := resource["usage"]: usage = ifcopenshell.api.resource.add_resource_time(self.file, resource=resource["ifc"]) @@ -227,7 +230,7 @@ class Csv2Ifc: if unit: return unit else: - unit = ifcopenshell.api.run("unit.add_si_unit", self.file, unit_type=unit_type) + unit = ifcopenshell.api.unit.add_si_unit(self.file, unit_type=unit_type) # unit = self.file.createIfcContextDependentUnit( # self.file.createIfcDimensionalExponents(0, 0, 0, 0, 0, 0, 0), "USERDEFINED", symbol # ) @@ -236,8 +239,8 @@ class Csv2Ifc: def create_boilerplate_ifc(self) -> None: self.file = ifcopenshell.file(schema="IFC4") - ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") - ifcopenshell.api.run("unit.assign_unit", self.file) + ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject") + ifcopenshell.api.unit.assign_unit(self.file) class Ifc2CsvRow(NamedTuple): diff --git a/src/ifc4d/ifc4d/csv4d2ifc.py b/src/ifc4d/ifc4d/csv4d2ifc.py index 36cf7d787e..9a33ea8198 100644 --- a/src/ifc4d/ifc4d/csv4d2ifc.py +++ b/src/ifc4d/ifc4d/csv4d2ifc.py @@ -20,6 +20,8 @@ import csv import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.root +import ifcopenshell.api.sequence import ifcopenshell.util.date import locale import re @@ -136,14 +138,14 @@ class Csv2Ifc: if not self.file: self.create_boilerplate_ifc() if not self.work_plan: - self.work_plan = ifcopenshell.api.run("sequence.add_work_plan", self.file) + self.work_plan = ifcopenshell.api.sequence.add_work_plan(self.file) self.work_schedule = self.create_work_schedule() self.create_tasks(self.tasks) self.create_rel_sequences(self.tasks) def create_boilerplate_ifc(self): self.file = ifcopenshell.file(schema="IFC4") - ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") + ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject") self.work_plan = self.file.create_entity("IfcWorkPlan") def create_tasks(self, tasks, parent=None): @@ -161,16 +163,15 @@ class Csv2Ifc: self.create_rel_sequence(task) def create_work_schedule(self): - return ifcopenshell.api.run("sequence.add_work_schedule", self.file, name="import", work_plan=self.work_plan) + return ifcopenshell.api.sequence.add_work_schedule(self.file, name="import", work_plan=self.work_plan) def create_task(self, task, parent_task=None): if parent_task is None: - task["ifc"] = ifcopenshell.api.run("sequence.add_task", self.file, work_schedule=self.work_schedule) + task["ifc"] = ifcopenshell.api.sequence.add_task(self.file, work_schedule=self.work_schedule) else: - task["ifc"] = ifcopenshell.api.run("sequence.add_task", self.file, parent_task=parent_task) + task["ifc"] = ifcopenshell.api.sequence.add_task(self.file, parent_task=parent_task) - ifcopenshell.api.run( - "sequence.edit_task", + ifcopenshell.api.sequence.edit_task( self.file, task=task["ifc"], attributes={ @@ -179,9 +180,8 @@ class Csv2Ifc: # "IsMilestone": task["ScheduleStart"] == task["ScheduleFinish"], }, ) - task_time = ifcopenshell.api.run("sequence.add_task_time", self.file, task=task["ifc"]) - ifcopenshell.api.run( - "sequence.edit_task_time", + task_time = ifcopenshell.api.sequence.add_task_time(self.file, task=task["ifc"]) + ifcopenshell.api.sequence.edit_task_time( self.file, task_time=task_time, attributes={ @@ -211,16 +211,14 @@ class Csv2Ifc: task_1 = self.get_entity_by_identification(self.tasks, rel["task_1"]) task_2 = self.get_entity_by_identification(self.tasks, rel["task_2"]) rel_type = self.sequence_type_map[rel["rel_type"]] - rel_sequence = ifcopenshell.api.run( - "sequence.assign_sequence", + rel_sequence = ifcopenshell.api.sequence.assign_sequence( self.file, related_process=task_2, relating_process=task_1, sequence_type=rel_type, ) if rel_type: - ifcopenshell.api.run( - "sequence.edit_sequence", + ifcopenshell.api.sequence.edit_sequence( self.file, rel_sequence=rel_sequence, attributes={"SequenceType": rel_type}, diff --git a/src/ifc4d/ifc4d/msp2ifc.py b/src/ifc4d/ifc4d/msp2ifc.py index 8d53429834..f8443db588 100644 --- a/src/ifc4d/ifc4d/msp2ifc.py +++ b/src/ifc4d/ifc4d/msp2ifc.py @@ -20,6 +20,10 @@ import datetime from datetime import timedelta, date import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.control +import ifcopenshell.api.pset +import ifcopenshell.api.root +import ifcopenshell.api.sequence import ifcopenshell.util.date import xml.etree.ElementTree as ET @@ -208,7 +212,7 @@ class MSP2Ifc: if not self.file: self.create_boilerplate_ifc() if not self.work_plan: - self.work_plan = ifcopenshell.api.run("sequence.add_work_plan", self.file) + self.work_plan = ifcopenshell.api.sequence.add_work_plan(self.file) work_schedule = self.create_work_schedule() self.create_calendars() self.create_tasks(work_schedule) @@ -216,7 +220,7 @@ class MSP2Ifc: def create_boilerplate_ifc(self): self.file = ifcopenshell.file(schema="IFC4") - ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") + ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject") self.work_plan = self.file.create_entity("IfcWorkPlan") def create_tasks(self, work_schedule): @@ -227,8 +231,8 @@ class MSP2Ifc: self.create_task(task, work_schedule=work_schedule) def create_work_schedule(self): - return ifcopenshell.api.run( - "sequence.add_work_schedule", self.file, name=self.project["Name"], work_plan=self.work_plan + return ifcopenshell.api.sequence.add_work_schedule( + self.file, name=self.project["Name"], work_plan=self.work_plan ) def create_calendars(self): @@ -238,13 +242,12 @@ class MSP2Ifc: for calendar in self.calendars.values(): if not has_work_or_exceptions(calendar): continue - calendar["ifc"] = ifcopenshell.api.run("sequence.add_work_calendar", self.file, name=calendar["Name"]) + calendar["ifc"] = ifcopenshell.api.sequence.add_work_calendar(self.file, name=calendar["Name"]) self.process_working_week(calendar["StandardWorkWeek"], calendar["ifc"]) self.process_exceptions(calendar["HolidayOrExceptions"], calendar["ifc"]) def create_task(self, task, work_schedule=None, parent_task=None): - task["ifc"] = ifcopenshell.api.run( - "sequence.add_task", + task["ifc"] = ifcopenshell.api.sequence.add_task( self.file, work_schedule=work_schedule if work_schedule else None, parent_task=parent_task["ifc"] if parent_task else None, @@ -257,8 +260,7 @@ class MSP2Ifc: calendar = self.calendars[self.project["CalendarUID"]]["ifc"] if calendar: - ifcopenshell.api.run( - "control.assign_control", + ifcopenshell.api.control.assign_control( self.file, **{ "relating_control": calendar, @@ -266,8 +268,7 @@ class MSP2Ifc: }, ) - ifcopenshell.api.run( - "sequence.edit_task", + ifcopenshell.api.sequence.edit_task( self.file, task=task["ifc"], attributes={ @@ -276,9 +277,8 @@ class MSP2Ifc: "IsMilestone": task["Start"] == task["Finish"], }, ) - task_time = ifcopenshell.api.run("sequence.add_task_time", self.file, task=task["ifc"]) - ifcopenshell.api.run( - "sequence.edit_task_time", + task_time = ifcopenshell.api.sequence.add_task_time(self.file, task=task["ifc"]) + ifcopenshell.api.sequence.edit_task_time( self.file, task_time=task_time, attributes={ @@ -293,10 +293,9 @@ class MSP2Ifc: # create pset for optional columns if len(self.optionalColumns): - pset = ifcopenshell.api.run("pset.add_pset", self.file, product=task["ifc"], name="Pset_MSP_Task") + pset = ifcopenshell.api.pset.add_pset(self.file, product=task["ifc"], name="Pset_MSP_Task") - ifcopenshell.api.run( - "pset.edit_pset", + ifcopenshell.api.pset.edit_pset( self.file, pset=pset, properties={name: str(task[name]) for name in self.optionalColumns if task[name]}, @@ -317,8 +316,8 @@ class MSP2Ifc: if day["ifc"]: continue - day["ifc"] = ifcopenshell.api.run( - "sequence.add_work_time", self.file, work_calendar=calendar, time_type="WorkingTimes" + day["ifc"] = ifcopenshell.api.sequence.add_work_time( + self.file, work_calendar=calendar, time_type="WorkingTimes" ) weekday_component = [day_map[day["DayType"]]] @@ -331,25 +330,22 @@ class MSP2Ifc: day2["ifc"] = day["ifc"] work_time_name = "Weekdays: {}".format(", ".join([str(c) for c in sorted(weekday_component)])) - ifcopenshell.api.run( - "sequence.edit_work_time", + ifcopenshell.api.sequence.edit_work_time( self.file, work_time=day["ifc"], attributes={"Name": work_time_name}, ) - recurrence = ifcopenshell.api.run( - "sequence.assign_recurrence_pattern", self.file, parent=day["ifc"], recurrence_type="WEEKLY" + recurrence = ifcopenshell.api.sequence.assign_recurrence_pattern( + self.file, parent=day["ifc"], recurrence_type="WEEKLY" ) - ifcopenshell.api.run( - "sequence.edit_recurrence_pattern", + ifcopenshell.api.sequence.edit_recurrence_pattern( self.file, recurrence_pattern=recurrence, attributes={"WeekdayComponent": weekday_component}, ) for work_time in day["WorkingTimes"]: - ifcopenshell.api.run( - "sequence.add_time_period", + ifcopenshell.api.sequence.add_time_period( self.file, recurrence_pattern=recurrence, start_time=work_time["Start"], @@ -367,15 +363,13 @@ class MSP2Ifc: if not task["PredecessorTasks"]: continue for predecessor in task["PredecessorTasks"].values(): - rel_sequence = ifcopenshell.api.run( - "sequence.assign_sequence", + rel_sequence = ifcopenshell.api.sequence.assign_sequence( self.file, related_process=task["ifc"], relating_process=self.tasks[predecessor["PredecessorTask"]]["ifc"], ) if predecessor["Type"]: - ifcopenshell.api.run( - "sequence.edit_sequence", + ifcopenshell.api.sequence.edit_sequence( self.file, rel_sequence=rel_sequence, attributes={"SequenceType": self.sequence_type_map[predecessor["Type"]]}, @@ -407,11 +401,10 @@ class MSP2Ifc: def process_exception(self, exception, calendar): if exception["ifc"] or not exception["FromDate"]: return - exception["ifc"] = ifcopenshell.api.run( - "sequence.add_work_time", self.file, work_calendar=calendar, time_type="ExceptionTimes" + exception["ifc"] = ifcopenshell.api.sequence.add_work_time( + self.file, work_calendar=calendar, time_type="ExceptionTimes" ) - ifcopenshell.api.run( - "sequence.edit_work_time", + ifcopenshell.api.sequence.edit_work_time( self.file, work_time=exception["ifc"], attributes={ @@ -441,18 +434,16 @@ class MSP2Ifc: } else: return - recurrence = ifcopenshell.api.run( - "sequence.assign_recurrence_pattern", + recurrence = ifcopenshell.api.sequence.assign_recurrence_pattern( self.file, parent=exception["ifc"], recurrence_type=recurrence_type, ) - ifcopenshell.api.run( - "sequence.edit_recurrence_pattern", self.file, recurrence_pattern=recurrence, attributes=attributes + ifcopenshell.api.sequence.edit_recurrence_pattern( + self.file, recurrence_pattern=recurrence, attributes=attributes ) for work_time in exception["WorkingTimes"] or []: - ifcopenshell.api.run( - "sequence.add_time_period", + ifcopenshell.api.sequence.add_time_period( self.file, recurrence_pattern=recurrence, start_time=work_time["Start"], diff --git a/src/ifccityjson/ifccityjson/cityjson2ifc/cityjson2ifc.py b/src/ifccityjson/ifccityjson/cityjson2ifc/cityjson2ifc.py index d24aadf9ff..50b06e6aa9 100644 --- a/src/ifccityjson/ifccityjson/cityjson2ifc/cityjson2ifc.py +++ b/src/ifccityjson/ifccityjson/cityjson2ifc/cityjson2ifc.py @@ -20,6 +20,11 @@ import os import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.context +import ifcopenshell.api.project +import ifcopenshell.api.pset +import ifcopenshell.api.root +import ifcopenshell.api.unit import ifcopenshell.guid from datetime import datetime @@ -166,16 +171,15 @@ class Cityjson2ifc: self.IFC_model.create_entity("IfcMapConversion", **self.properties["local_translation"]) def create_new_file(self): - self.IFC_model = ifcopenshell.api.run("project.create_file") - self.IFC_project = ifcopenshell.api.run( - "root.create_entity", + self.IFC_model = ifcopenshell.api.project.create_file() + self.IFC_project = ifcopenshell.api.root.create_entity( self.IFC_model, **{"ifc_class": "IfcProject", "name": self.properties.get("name_project", "My Project")}, ) - ifcopenshell.api.run("unit.assign_unit", self.IFC_model, length={"is_metric": True, "raw": "METERS"}) + ifcopenshell.api.unit.assign_unit(self.IFC_model, length={"is_metric": True, "raw": "METERS"}) self.properties["owner_history"] = self.create_owner_history() - self.IFC_representation_context = ifcopenshell.api.run( - "context.add_context", self.IFC_model, **{"context_type": "Model"} + self.IFC_representation_context = ifcopenshell.api.context.add_context( + self.IFC_model, **{"context_type": "Model"} ) if not self.city_model.has_metadata() or "presentLoDs" not in self.city_model.j["metadata"]: @@ -184,8 +188,7 @@ class Cityjson2ifc: # create IFC representation subcontexts from lods self.create_representation_sub_contexts() - self.IFC_site = ifcopenshell.api.run( - "root.create_entity", + self.IFC_site = ifcopenshell.api.root.create_entity( self.IFC_model, **{"ifc_class": "IfcSite", "name": self.properties.get("name_site", "My Site")}, ) @@ -205,7 +208,7 @@ class Cityjson2ifc: def create_representation_sub_context(self, lod): # TODO in ifcopenshell.api.context.add_context add support for UserDefinedTargetView - # self.IFC_representation_sub_contexts[str(lod)] = ifcopenshell.api.run("context.add_context", self.IFC_model, + # self.IFC_representation_sub_contexts[str(lod)] = ifcopenshell.api.context.add_context( self.IFC_model, # **{"context": "Model", # "subcontext": "Body", # "target_view": "USERDEFINED", @@ -269,9 +272,9 @@ class Cityjson2ifc: for element in representations_in_context: IFC_copied_model.remove(element) # slow: - # ifcopenshell.api.run("geometry.remove_representation", IFC_copied_model, representation=element) + # ifcopenshell.api.geometry.remove_representation( IFC_copied_model, representation=element) - ifcopenshell.api.run("context.remove_context", IFC_copied_model, context=sub_context) + ifcopenshell.api.context.remove_context(IFC_copied_model, context=sub_context) IFC_copied_model.write(file) del IFC_copied_model @@ -404,5 +407,5 @@ class Cityjson2ifc: if len(CJ_attributes) == 0: return - pset = ifcopenshell.api.run("pset.add_pset", self.IFC_model, product=IFC_entity, name="CityJSON_attributes") - ifcopenshell.api.run("pset.edit_pset", self.IFC_model, pset=pset, properties=CJ_attributes) + pset = ifcopenshell.api.pset.add_pset(self.IFC_model, product=IFC_entity, name="CityJSON_attributes") + ifcopenshell.api.pset.edit_pset(self.IFC_model, pset=pset, properties=CJ_attributes) diff --git a/src/ifcdiff/test.py b/src/ifcdiff/test.py index fa0aee15ea..c9e632091f 100644 --- a/src/ifcdiff/test.py +++ b/src/ifcdiff/test.py @@ -21,14 +21,15 @@ import ifcopenshell import ifcopenshell.api.context import ifcopenshell.api.geometry import ifcopenshell.api.root +import ifcopenshell.api.unit import ifcopenshell.util.representation def setup_project() -> ifcopenshell.file: ifc_file = ifcopenshell.file(schema="IFC4") - ifcopenshell.api.run("root.create_entity", ifc_file, ifc_class="IfcProject") - unit = ifcopenshell.api.run("unit.add_si_unit", ifc_file, unit_type="LENGTHUNIT", prefix="MILLI") - ifcopenshell.api.run("unit.assign_unit", ifc_file, units=[unit]) + ifcopenshell.api.root.create_entity(ifc_file, ifc_class="IfcProject") + unit = ifcopenshell.api.unit.add_si_unit(ifc_file, unit_type="LENGTHUNIT", prefix="MILLI") + ifcopenshell.api.unit.assign_unit(ifc_file, units=[unit]) model = ifcopenshell.api.context.add_context(ifc_file, "Model") ifcopenshell.api.context.add_context(ifc_file, "Model", "Body", "MODEL_VIEW", parent=model) return ifc_file diff --git a/src/ifcopenshell-python/test/api/alignment/test_add_stationing_to_alignment.py b/src/ifcopenshell-python/test/api/alignment/test_add_stationing_to_alignment.py index 19017db300..765a9b4838 100644 --- a/src/ifcopenshell-python/test/api/alignment/test_add_stationing_to_alignment.py +++ b/src/ifcopenshell-python/test/api/alignment/test_add_stationing_to_alignment.py @@ -19,6 +19,7 @@ import pytest import ifcopenshell.api.alignment import ifcopenshell.api.context +import ifcopenshell.util.element def test_add_stationing_to_alignment(): diff --git a/src/ifcopenshell-python/test/api/context/test_remove_context.py b/src/ifcopenshell-python/test/api/context/test_remove_context.py index c941021eeb..dbc4185b6c 100644 --- a/src/ifcopenshell-python/test/api/context/test_remove_context.py +++ b/src/ifcopenshell-python/test/api/context/test_remove_context.py @@ -18,6 +18,8 @@ import test.bootstrap import ifcopenshell.api.context +import ifcopenshell.api.geometry +import ifcopenshell.api.root class TestRemoveContext(test.bootstrap.IFC4): diff --git a/src/ifcopenshell-python/test/api/feature/test_add_feature.py b/src/ifcopenshell-python/test/api/feature/test_add_feature.py index 81ed56ff19..7ac05f6ecf 100644 --- a/src/ifcopenshell-python/test/api/feature/test_add_feature.py +++ b/src/ifcopenshell-python/test/api/feature/test_add_feature.py @@ -22,6 +22,7 @@ import ifcopenshell.api.feature import ifcopenshell.api.root import ifcopenshell.api.unit import ifcopenshell.api.geometry +import ifcopenshell.util.placement class TestAddFeature(test.bootstrap.IFC4X3): diff --git a/src/ifcopenshell-python/test/api/geometry/test_add_boolean.py b/src/ifcopenshell-python/test/api/geometry/test_add_boolean.py index 07a4400f5a..f47524762e 100644 --- a/src/ifcopenshell-python/test/api/geometry/test_add_boolean.py +++ b/src/ifcopenshell-python/test/api/geometry/test_add_boolean.py @@ -20,6 +20,7 @@ import test.bootstrap import ifcopenshell.api.root import ifcopenshell.api.context import ifcopenshell.api.geometry +import ifcopenshell.util.shape_builder class TestAddBoolean(test.bootstrap.IFC4): diff --git a/src/ifcopenshell-python/test/api/geometry/test_remove_boolean.py b/src/ifcopenshell-python/test/api/geometry/test_remove_boolean.py index 5b98fc0de0..5330d097cc 100644 --- a/src/ifcopenshell-python/test/api/geometry/test_remove_boolean.py +++ b/src/ifcopenshell-python/test/api/geometry/test_remove_boolean.py @@ -20,6 +20,7 @@ import test.bootstrap import ifcopenshell.api.root import ifcopenshell.api.context import ifcopenshell.api.geometry +import ifcopenshell.util.shape_builder class TestRemoveBoolean(test.bootstrap.IFC4): diff --git a/src/ifcopenshell-python/test/api/geometry/test_validate_type.py b/src/ifcopenshell-python/test/api/geometry/test_validate_type.py index 6eed24efcb..189f9619a9 100644 --- a/src/ifcopenshell-python/test/api/geometry/test_validate_type.py +++ b/src/ifcopenshell-python/test/api/geometry/test_validate_type.py @@ -20,6 +20,7 @@ import test.bootstrap import ifcopenshell.api.root import ifcopenshell.api.context import ifcopenshell.api.geometry +import ifcopenshell.util.shape_builder class TestValidateType(test.bootstrap.IFC4): diff --git a/src/ifcopenshell-python/test/api/owner/test_update_owner_history.py b/src/ifcopenshell-python/test/api/owner/test_update_owner_history.py index b90eec9882..fb500658e1 100644 --- a/src/ifcopenshell-python/test/api/owner/test_update_owner_history.py +++ b/src/ifcopenshell-python/test/api/owner/test_update_owner_history.py @@ -19,6 +19,7 @@ import time import test.bootstrap import ifcopenshell.api.owner +import ifcopenshell.api.owner.settings class TestUpdateOwnerHistory(test.bootstrap.IFC4): @@ -33,6 +34,7 @@ class TestUpdateOwnerHistory(test.bootstrap.IFC4): element = self.file.createIfcWall() history = ifcopenshell.api.owner.update_owner_history(self.file, element=element) + assert history assert history.is_a("IfcOwnerHistory") assert element.OwnerHistory == history assert history.ChangeAction == "ADDED" @@ -57,6 +59,7 @@ class TestUpdateOwnerHistory(test.bootstrap.IFC4): element.OwnerHistory = old_history new_history = ifcopenshell.api.owner.update_owner_history(self.file, element=element) + assert new_history assert new_history == old_history assert element.OwnerHistory == new_history assert new_history.ChangeAction == "MODIFIED" @@ -83,6 +86,7 @@ class TestUpdateOwnerHistory(test.bootstrap.IFC4): element2.OwnerHistory = old_history new_history = ifcopenshell.api.owner.update_owner_history(self.file, element=element) + assert new_history assert new_history != old_history assert element.OwnerHistory == new_history assert new_history.ChangeAction == "MODIFIED" diff --git a/src/ifcopenshell-python/test/file_gc.py b/src/ifcopenshell-python/test/file_gc.py index 85d2d70e43..8cff9a7e38 100644 --- a/src/ifcopenshell-python/test/file_gc.py +++ b/src/ifcopenshell-python/test/file_gc.py @@ -76,6 +76,8 @@ def test_file_gc(args): def test_bug_2517(): fixtures = os.path.join(os.path.dirname(__file__), "fixtures") + model: ifcopenshell.file + library: ifcopenshell.file model = ifcopenshell.open(f"{fixtures}/bug_2517_test2.ifc") library = ifcopenshell.open(f"{fixtures}/bug_2517_lib.ifc") result = model.add(library.by_type("IfcClassification")[0]) diff --git a/src/ifcopenshell-python/test/geom/settings.py b/src/ifcopenshell-python/test/geom/settings.py index e83218ec82..c4e24b2027 100644 --- a/src/ifcopenshell-python/test/geom/settings.py +++ b/src/ifcopenshell-python/test/geom/settings.py @@ -18,9 +18,11 @@ import numpy as np import ifcopenshell +import ifcopenshell.api.context import ifcopenshell.api.geometry import ifcopenshell.api.profile import ifcopenshell.api.root +import ifcopenshell.api.unit import ifcopenshell.geom import ifcopenshell.geom import ifcopenshell.util.unit @@ -37,9 +39,9 @@ class TestSettings(test.bootstrap.IFC4): builder = ShapeBuilder(ifc_file) ifcopenshell.api.root.create_entity(ifc_file, "IfcProject") - unit = ifcopenshell.api.run("unit.add_si_unit", ifc_file, unit_type="LENGTHUNIT", prefix="MILLI") - ifcopenshell.api.run("unit.assign_unit", ifc_file, units=[unit]) - model = ifcopenshell.api.run("context.add_context", ifc_file, context_type="Model") + unit = ifcopenshell.api.unit.add_si_unit(ifc_file, unit_type="LENGTHUNIT", prefix="MILLI") + ifcopenshell.api.unit.assign_unit(ifc_file, units=[unit]) + model = ifcopenshell.api.context.add_context(ifc_file, context_type="Model") # Placement. element = ifcopenshell.api.root.create_entity(ifc_file, "IfcWall") diff --git a/src/ifcopenshell-python/test/test_stream.py b/src/ifcopenshell-python/test/test_stream.py index f9c3b1c710..e425fd1583 100644 --- a/src/ifcopenshell-python/test/test_stream.py +++ b/src/ifcopenshell-python/test/test_stream.py @@ -26,15 +26,18 @@ TEST_FILE = Path(__file__).parent / "files" / "basic.ifc" class TestFile: def test_run(self): + stream_file: ifcopenshell.stream stream_file = ifcopenshell.open(TEST_FILE, should_stream=True) assert stream_file.schema == "IFC4" def test_by_id(self): + stream_file: ifcopenshell.stream stream_file = ifcopenshell.open(TEST_FILE, should_stream=True) assert (element := stream_file.by_id(1)) assert str(element) == "#1=IFCPROJECT('3kv235yMjDO9tHiTzD8QuS',$,'My Project',$,$,$,$,(#14,#26),#9);" def test_by_type(self): + stream_file: ifcopenshell.stream stream_file = ifcopenshell.open(TEST_FILE, should_stream=True) assert (elements := stream_file.by_type("IfcProject")) assert str(elements[0]) == "#1=IFCPROJECT('3kv235yMjDO9tHiTzD8QuS',$,'My Project',$,$,$,$,(#14,#26),#9);" @@ -42,6 +45,7 @@ class TestFile: class TestEntity: def test_getattr(self): + stream_file: ifcopenshell.stream stream_file = ifcopenshell.open(TEST_FILE, should_stream=True) assert (element := stream_file.by_id(1)) assert element.Name == "My Project" diff --git a/src/ifcopenshell-python/test/test_write.py b/src/ifcopenshell-python/test/test_write.py index e98a539dcb..356f46c6fc 100644 --- a/src/ifcopenshell-python/test/test_write.py +++ b/src/ifcopenshell-python/test/test_write.py @@ -26,6 +26,8 @@ TEST_FILE_DIR = Path("../../test/input/") class TestWrite: + model: ifcopenshell.file + def setup_method(self): self.model = ifcopenshell.open(TEST_FILE_DIR / "WallInstance_IFC4Add2.ifc") diff --git a/src/ifcopenshell-python/test/util/test_shape_builder.py b/src/ifcopenshell-python/test/util/test_shape_builder.py index 1d1e00900e..4313c37507 100644 --- a/src/ifcopenshell-python/test/util/test_shape_builder.py +++ b/src/ifcopenshell-python/test/util/test_shape_builder.py @@ -38,7 +38,7 @@ from typing import Any, Union class TestMathutilsCompatibleMethods(test.bootstrap.IFC4): def test_np_rotation_matrix(self): - from mathutils import Matrix, Vector + from mathutils import Matrix, Vector # pyright: ignore[reportMissingImports] # 2D. assert np.allclose(Matrix.Rotation(radians(45), 2), np_rotation_matrix(radians(45), 2)) @@ -59,7 +59,7 @@ class TestMathutilsCompatibleMethods(test.bootstrap.IFC4): assert np.allclose(Matrix.Rotation(*rotation_vector_args), np_rotation_matrix(*rotation_vector_args)) def test_np_matrix_to_euler(self): - from mathutils import Euler + from mathutils import Euler # pyright: ignore[reportMissingImports] # Test 3x3. rot = Euler((0.5, 0.5, 0.5)).to_matrix() @@ -74,7 +74,7 @@ class TestMathutilsCompatibleMethods(test.bootstrap.IFC4): assert np.allclose(rot.to_euler(), np_matrix_to_euler(V(rot))) def test_np_angle(self): - from mathutils import Vector + from mathutils import Vector # pyright: ignore[reportMissingImports] v1, v2 = (1, 0, 0), (0, 1, 0) angle = np_angle(v1, v2) @@ -97,7 +97,7 @@ class TestMathutilsCompatibleMethods(test.bootstrap.IFC4): assert is_x(angle, radians(90)) def test_np_normal(self): - import mathutils.geometry + import mathutils.geometry # pyright: ignore[reportMissingImports] vectors = (0, 0, 0), (1, 0, 0), (0, 1, 0) n = mathutils.geometry.normal(vectors) @@ -110,7 +110,7 @@ class TestMathutilsCompatibleMethods(test.bootstrap.IFC4): assert np.allclose(n, (0, 0, -1)) def test_np_intersect_line_line(self): - import mathutils.geometry + import mathutils.geometry # pyright: ignore[reportMissingImports] p1, p2 = [0, 0, 0], [1, 1, 1] q1, q2 = [0, 1, 0], [1, 0, 1] diff --git a/src/ifcpatch/test/bootstrap.py b/src/ifcpatch/test/bootstrap.py index 963a8d0d7a..d4d1d07c2e 100644 --- a/src/ifcpatch/test/bootstrap.py +++ b/src/ifcpatch/test/bootstrap.py @@ -19,13 +19,14 @@ import pytest import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.project import ifcopenshell.api.owner.settings class IFC4X3: @pytest.fixture(autouse=True) def setup(self): - self.file: ifcopenshell.file = ifcopenshell.api.run("project.create_file", version="IFC4X3") + self.file: ifcopenshell.file = ifcopenshell.api.project.create_file(version="IFC4X3") ifcopenshell.api.owner.settings.get_user = lambda ifc: (ifc.by_type("IfcPersonAndOrganization") or [None])[0] ifcopenshell.api.owner.settings.get_application = lambda ifc: (ifc.by_type("IfcApplication") or [None])[0] ifcopenshell.api.pre_listeners = {} @@ -35,7 +36,7 @@ class IFC4X3: class IFC4: @pytest.fixture(autouse=True) def setup(self): - self.file: ifcopenshell.file = ifcopenshell.api.run("project.create_file") + self.file: ifcopenshell.file = ifcopenshell.api.project.create_file() ifcopenshell.api.owner.settings.get_user = lambda ifc: (ifc.by_type("IfcPersonAndOrganization") or [None])[0] ifcopenshell.api.owner.settings.get_application = lambda ifc: (ifc.by_type("IfcApplication") or [None])[0] ifcopenshell.api.pre_listeners = {} @@ -45,7 +46,7 @@ class IFC4: class IFC2X3: @pytest.fixture(autouse=True) def setup(self): - self.file: ifcopenshell.file = ifcopenshell.api.run("project.create_file", version="IFC2X3") + self.file: ifcopenshell.file = ifcopenshell.api.project.create_file(version="IFC2X3") def get_user(ifc_file: ifcopenshell.file) -> ifcopenshell.entity_instance: person = ifcopenshell.api.owner.add_person(ifc_file) diff --git a/src/ifcpatch/test/test_ExtractElements.py b/src/ifcpatch/test/test_ExtractElements.py index bc6ef48b0d..8df5095256 100644 --- a/src/ifcpatch/test/test_ExtractElements.py +++ b/src/ifcpatch/test/test_ExtractElements.py @@ -21,29 +21,32 @@ import pytest import ifcpatch import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.aggregate +import ifcopenshell.api.root +import ifcopenshell.api.spatial import ifcopenshell.util.element import test.bootstrap class TestExtractElements(test.bootstrap.IFC4): def test_basic(self): - project = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") - wall = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") + project = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject") + wall = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall") output = ifcpatch.execute({"file": self.file, "recipe": "ExtractElements", "arguments": ["IfcWall"]}) assert output.by_type("IfcProject")[0].GlobalId == project.GlobalId assert output.by_type("IfcWall")[0].GlobalId == wall.GlobalId def test_keep_spatial_structure(self): - project = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") + project = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject") - site = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSite") - building = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding") - storey = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuildingStorey") - wall = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") - ifcopenshell.api.run("aggregate.assign_object", self.file, products=[building], relating_object=site) - ifcopenshell.api.run("aggregate.assign_object", self.file, products=[storey], relating_object=building) - ifcopenshell.api.run("spatial.assign_container", self.file, products=[wall], relating_structure=storey) + site = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcSite") + building = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcBuilding") + storey = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcBuildingStorey") + wall = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall") + ifcopenshell.api.aggregate.assign_object(self.file, products=[building], relating_object=site) + ifcopenshell.api.aggregate.assign_object(self.file, products=[storey], relating_object=building) + ifcopenshell.api.spatial.assign_container(self.file, products=[wall], relating_structure=storey) output = ifcpatch.execute({"file": self.file, "recipe": "ExtractElements", "arguments": ["IfcWall"]}) @@ -53,13 +56,13 @@ class TestExtractElements(test.bootstrap.IFC4): assert (site_new := ifcopenshell.util.element.get_aggregate(building_new)).GlobalId == site.GlobalId def test_keep_aggregate_in_spatial_structure(self): - project = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") + project = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject") - element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcElementAssembly") - container = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuildingStorey") - subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") - ifcopenshell.api.run("spatial.assign_container", self.file, products=[element], relating_structure=container) - ifcopenshell.api.run("aggregate.assign_object", self.file, products=[subelement], relating_object=element) + element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcElementAssembly") + container = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcBuildingStorey") + subelement = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall") + ifcopenshell.api.spatial.assign_container(self.file, products=[element], relating_structure=container) + ifcopenshell.api.aggregate.assign_object(self.file, products=[subelement], relating_object=element) output = ifcpatch.execute({"file": self.file, "recipe": "ExtractElements", "arguments": ["IfcWall"]}) @@ -84,8 +87,8 @@ class TestExtractElements(test.bootstrap.IFC4): ) def test_extracting_non_standard_schema_version(self): self.file = ifcopenshell.file(schema_version=(4, 3, 0, 0)) - project = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") - wall = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") + project = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject") + wall = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall") output = ifcpatch.execute({"file": self.file, "recipe": "ExtractElements", "arguments": ["IfcWall"]}) assert output.by_type("IfcProject")[0].GlobalId == project.GlobalId assert output.by_type("IfcWall")[0].GlobalId == wall.GlobalId diff --git a/src/ifcpatch/test/test_MergeDuplicateTypes.py b/src/ifcpatch/test/test_MergeDuplicateTypes.py index 3149f30ca4..9abc29c044 100644 --- a/src/ifcpatch/test/test_MergeDuplicateTypes.py +++ b/src/ifcpatch/test/test_MergeDuplicateTypes.py @@ -21,6 +21,10 @@ import pytest import ifcpatch import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.geometry +import ifcopenshell.api.material +import ifcopenshell.api.root +import ifcopenshell.api.type import ifcopenshell.util.element import ifcopenshell.util.representation import test.bootstrap @@ -30,26 +34,24 @@ class TestMergeDuplicateTypes(test.bootstrap.IFC4): def test_run(self): context = self.file.createIfcGeometricRepresentationContext() - wall1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") - wall_type1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType", name="WallType") + wall1 = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall") + wall_type1 = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWallType", name="WallType") rep = self.file.createIfcShapeRepresentation(ContextOfItems=context) - ifcopenshell.api.run("geometry.assign_representation", self.file, product=wall_type1, representation=rep) - ifcopenshell.api.run("material.assign_material", self.file, products=[wall_type1], type="IfcMaterialLayerSet") - ifcopenshell.api.run( - "type.assign_type", + ifcopenshell.api.geometry.assign_representation(self.file, product=wall_type1, representation=rep) + ifcopenshell.api.material.assign_material(self.file, products=[wall_type1], type="IfcMaterialLayerSet") + ifcopenshell.api.type.assign_type( self.file, related_objects=[wall1], relating_type=wall_type1, should_map_representations=False, ) - wall2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") - wall_type2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType", name="WallType") + wall2 = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall") + wall_type2 = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWallType", name="WallType") rep = self.file.createIfcShapeRepresentation(ContextOfItems=context) - ifcopenshell.api.run("geometry.assign_representation", self.file, product=wall_type2, representation=rep) - ifcopenshell.api.run("material.assign_material", self.file, products=[wall_type2], type="IfcMaterialLayerSet") - ifcopenshell.api.run( - "type.assign_type", + ifcopenshell.api.geometry.assign_representation(self.file, product=wall_type2, representation=rep) + ifcopenshell.api.material.assign_material(self.file, products=[wall_type2], type="IfcMaterialLayerSet") + ifcopenshell.api.type.assign_type( self.file, related_objects=[wall2], relating_type=wall_type2, diff --git a/src/ifcpatch/test/test_MergeProject.py b/src/ifcpatch/test/test_MergeProject.py index 73b114374d..6384e98dd8 100644 --- a/src/ifcpatch/test/test_MergeProject.py +++ b/src/ifcpatch/test/test_MergeProject.py @@ -21,6 +21,8 @@ import ifcopenshell import ifcopenshell.api.context import ifcopenshell.api.geometry import ifcopenshell.api.georeference +import ifcopenshell.api.root +import ifcopenshell.api.unit import ifcopenshell.geom import ifcopenshell.util.geolocation import ifcopenshell.util.placement @@ -40,16 +42,16 @@ class TestMergeProjects(test.bootstrap.IFC4): if ifc_file is None: ifc_file = ifcopenshell.file(schema=self.file.schema) - ifcopenshell.api.run("root.create_entity", ifc_file, ifc_class="IfcProject") - unit = ifcopenshell.api.run("unit.add_si_unit", ifc_file, unit_type="LENGTHUNIT", prefix=prefix) - ifcopenshell.api.run("unit.assign_unit", ifc_file, units=[unit]) + ifcopenshell.api.root.create_entity(ifc_file, ifc_class="IfcProject") + unit = ifcopenshell.api.unit.add_si_unit(ifc_file, unit_type="LENGTHUNIT", prefix=prefix) + ifcopenshell.api.unit.assign_unit(ifc_file, units=[unit]) model = ifcopenshell.api.context.add_context(ifc_file, "Model") ifcopenshell.api.context.add_context(ifc_file, "Model", "Body", "MODEL_VIEW", parent=model) matrix = np.eye(4) matrix[:, 3] = (1, 2, 3, 1) - wall = ifcopenshell.api.run("root.create_entity", ifc_file, ifc_class="IfcWall") - ifcopenshell.api.run("geometry.edit_object_placement", ifc_file, product=wall, matrix=matrix, is_si=True) + wall = ifcopenshell.api.root.create_entity(ifc_file, ifc_class="IfcWall") + ifcopenshell.api.geometry.edit_object_placement(ifc_file, product=wall, matrix=matrix, is_si=True) return ifc_file def test_run(self): diff --git a/src/ifcpatch/test/test_RegenerateGlobalIds.py b/src/ifcpatch/test/test_RegenerateGlobalIds.py index ae33b60747..3cc4d9026f 100644 --- a/src/ifcpatch/test/test_RegenerateGlobalIds.py +++ b/src/ifcpatch/test/test_RegenerateGlobalIds.py @@ -21,23 +21,24 @@ import pytest import ifcpatch import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.root import ifcopenshell.util.element import test.bootstrap class TestRegenerateGlobalIds(test.bootstrap.IFC4): def test_run(self): - project = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") - wall = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") + project = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject") + wall = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall") used_guids = {project.GlobalId, wall.GlobalId} ifcpatch.execute({"file": self.file, "recipe": "RegenerateGlobalIds", "arguments": [False]}) new_guids = {project.GlobalId, wall.GlobalId} assert not new_guids.intersection(used_guids) def test_regenerate_guids_for_duplicates(self): - project = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") - wall1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") - wall2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") + project = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject") + wall1 = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall") + wall2 = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall") wall1.GlobalId = wall2.GlobalId used_guids = {project, wall1.GlobalId, wall2.GlobalId} diff --git a/src/ifcsverchok/__init__.py b/src/ifcsverchok/__init__.py index 2296e1ce5a..c655baed52 100644 --- a/src/ifcsverchok/__init__.py +++ b/src/ifcsverchok/__init__.py @@ -143,6 +143,9 @@ reload_event = False from os.path import splitext import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.aggregate +import ifcopenshell.api.root +import ifcopenshell.api.spatial import ifcopenshell.util.element from ifcsverchok.ifcstore import SvIfcStore @@ -201,7 +204,7 @@ class IFC_Sv_write_file(bpy.types.Operator, ExportHelper): def ensure_hirarchy(self, file: ifcopenshell.file) -> None: elements_in_buildings: set[ifcopenshell.entity_instance] = set() if len(file.by_type("IfcBuilding")) == 0: - my_building = ifcopenshell.api.run("root.create_entity", file, ifc_class="IfcBuilding", name="My Building") + my_building = ifcopenshell.api.root.create_entity(file, ifc_class="IfcBuilding", name="My Building") elements = ifcopenshell.util.element.get_decomposition(my_building) else: for building in file.by_type("IfcBuilding"): @@ -211,8 +214,8 @@ class IFC_Sv_write_file(bpy.types.Operator, ExportHelper): for spatial in file.by_type("IfcSpatialElement") or file.by_type("IfcSpatialStructureElement"): if not (spatial.is_a("IfcSite") or spatial.is_a("IfcBuilding")) and (spatial not in elements_in_buildings): elements = ifcopenshell.util.element.get_decomposition(spatial) - ifcopenshell.api.run( - "aggregate.assign_object", file, products=[spatial], relating_object=file.by_type("IfcBuilding")[0] + ifcopenshell.api.aggregate.assign_object( + file, products=[spatial], relating_object=file.by_type("IfcBuilding")[0] ) for building in file.by_type("IfcBuilding"): @@ -222,8 +225,7 @@ class IFC_Sv_write_file(bpy.types.Operator, ExportHelper): elements = file.by_type("IfcElement") for element in elements: if element not in elements_in_buildings: - ifcopenshell.api.run( - "spatial.assign_container", + ifcopenshell.api.spatial.assign_container( file, products=[element], relating_structure=file.by_type("IfcBuilding")[0], @@ -233,17 +235,16 @@ class IFC_Sv_write_file(bpy.types.Operator, ExportHelper): elements = ifcopenshell.util.element.get_decomposition(building) if not building.Decomposes: if len(file.by_type("IfcSite")) == 0: - ifcopenshell.api.run("root.create_entity", file, ifc_class="IfcSite", name="My Site") - ifcopenshell.api.run( - "aggregate.assign_object", file, products=[building], relating_object=file.by_type("IfcSite")[0] + ifcopenshell.api.root.create_entity(file, ifc_class="IfcSite", name="My Site") + ifcopenshell.api.aggregate.assign_object( + file, products=[building], relating_object=file.by_type("IfcSite")[0] ) try: if file.by_type("IfcSite")[0].Decomposes[0].RelatingObject.is_a("IfcProject"): continue except IndexError: pass - ifcopenshell.api.run( - "aggregate.assign_object", + ifcopenshell.api.aggregate.assign_object( file, products=[file.by_type("IfcSite")[0]], relating_object=file.by_type("IfcProject")[0], diff --git a/src/ifcsverchok/ifcstore.py b/src/ifcsverchok/ifcstore.py index d89ff83830..e99a97aa6d 100644 --- a/src/ifcsverchok/ifcstore.py +++ b/src/ifcsverchok/ifcstore.py @@ -19,6 +19,7 @@ import bpy import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.context import ifcopenshell.util.representation from ifcopenshell import template from typing import Union, Any @@ -80,8 +81,7 @@ class SvIfcStore: # TODO change units to imperial pass model = ifcopenshell.util.representation.get_context(file, context="Model") - context = ifcopenshell.api.run( - "context.add_context", + context = ifcopenshell.api.context.add_context( file, context_type="Model", context_identifier="Body", diff --git a/src/ifcsverchok/nodes/ifc/add_spatial_element.py b/src/ifcsverchok/nodes/ifc/add_spatial_element.py index 77cb1fba3f..78cae88e1b 100644 --- a/src/ifcsverchok/nodes/ifc/add_spatial_element.py +++ b/src/ifcsverchok/nodes/ifc/add_spatial_element.py @@ -22,6 +22,9 @@ from itertools import chain import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.aggregate +import ifcopenshell.api.root +import ifcopenshell.api.spatial import ifcopenshell.util.element import ifcsverchok.helper from ifcsverchok.ifcstore import SvIfcStore @@ -124,23 +127,20 @@ class SvIfcAddSpatialElement(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h if index is not None: iterator = [index] for i in iterator: - result = ifcopenshell.api.run( - "root.create_entity", + result = ifcopenshell.api.root.create_entity( self.file, name=self.names[i], ifc_class=self.ifc_class, ) for items in self.elements[i]: if items.is_a("IfcSpatialElement") or items.is_a("IfcSpatialStructureElement"): - ifcopenshell.api.run( - "aggregate.assign_object", + ifcopenshell.api.aggregate.assign_object( self.file, products=[items], relating_object=result, ) else: - ifcopenshell.api.run( - "spatial.assign_container", + ifcopenshell.api.spatial.assign_container( self.file, products=[items], relating_structure=result, @@ -170,30 +170,26 @@ class SvIfcAddSpatialElement(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h if removed_element.is_a("IfcSpatialElement") or removed_element.is_a( "IfcSpatialStructureElement" ): - ifcopenshell.api.run( - "aggregate.unassign_object", + ifcopenshell.api.aggregate.unassign_object( self.file, products=[removed_element], relating_object=result, ) else: - ifcopenshell.api.run( - "spatial.unassign_container", + ifcopenshell.api.spatial.unassign_container( self.file, products=[removed_element], relating_object=result, ) for added_element in element_set - subelements: if added_element.is_a("IfcSpatialElement") or added_element.is_a("IfcSpatialStructureElement"): - ifcopenshell.api.run( - "aggregate.assign_object", + ifcopenshell.api.aggregate.assign_object( self.file, products=[added_element], relating_object=result, ) else: - ifcopenshell.api.run( - "spatial.assign_container", + ifcopenshell.api.spatial.assign_container( self.file, products=[added_element], relating_structure=result, @@ -206,7 +202,7 @@ class SvIfcAddSpatialElement(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h if self.node_id in SvIfcStore.id_map: for element_id in SvIfcStore.id_map[self.node_id]: element = self.file.by_id(element_id) - ifcopenshell.api.run("root.remove_product", self.file, product=element) + ifcopenshell.api.root.remove_product(self.file, product=element) del SvIfcStore.id_map[self.node_id] def repeat_input_unique(self, input, count): diff --git a/src/ifcsverchok/nodes/ifc/bmesh_to_ifc.py b/src/ifcsverchok/nodes/ifc/bmesh_to_ifc.py index 6e8cb3df05..ab748ecd50 100644 --- a/src/ifcsverchok/nodes/ifc/bmesh_to_ifc.py +++ b/src/ifcsverchok/nodes/ifc/bmesh_to_ifc.py @@ -23,6 +23,7 @@ import bpy import ifcopenshell import ifcsverchok.helper import ifcopenshell.api +import ifcopenshell.api.context import ifcopenshell.api.geometry import ifcopenshell.util.representation from ifcsverchok.ifcstore import SvIfcStore @@ -224,8 +225,7 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help return for obj in SvIfcStore.id_map[self.node_id]["Representations"]: for step_id in obj: - ifcopenshell.api.run( - "geometry.remove_representation", + ifcopenshell.api.geometry.remove_representation( self.file, representation=self.file.by_id(step_id[0]), ) @@ -240,9 +240,8 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help if not context: parent = ifcopenshell.util.representation.get_context(self.file, self.context_type) if not parent: - parent = ifcopenshell.api.run("context.add_context", self.file, context_type=self.context_type) - context = ifcopenshell.api.run( - "context.add_context", + parent = ifcopenshell.api.context.add_context(self.file, context_type=self.context_type) + context = ifcopenshell.api.context.add_context( self.file, context_type=self.context_type, context_identifier=self.context_identifier, @@ -258,8 +257,7 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help if "Representations" in SvIfcStore.id_map[self.node_id]: for obj in SvIfcStore.id_map[self.node_id]["Representations"]: for step_id in obj: - ifcopenshell.api.run( - "geometry.remove_representation", + ifcopenshell.api.geometry.remove_representation( self.file, representation=self.file.by_id(step_id), ) @@ -270,10 +268,10 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help if not self.file.get_inverse(context): if self.file.by_id(context_id).ParentContext: parent = self.file.by_id(context_id).ParentContext - ifcopenshell.api.run("context.remove_context", self.file, context=context) + ifcopenshell.api.context.remove_context(self.file, context=context) if parent: if not self.file.get_inverse(parent): - ifcopenshell.api.run("context.remove_context", self.file, context=parent) + ifcopenshell.api.context.remove_context(self.file, context=parent) SvIfcStore.id_map[self.node_id]["Contexts"].remove(context_id) del SvIfcStore.id_map[self.node_id] del self.node_dict[hash(self)] diff --git a/src/ifcsverchok/nodes/ifc/create_project.py b/src/ifcsverchok/nodes/ifc/create_project.py index d228267d88..cc782de19d 100644 --- a/src/ifcsverchok/nodes/ifc/create_project.py +++ b/src/ifcsverchok/nodes/ifc/create_project.py @@ -19,6 +19,9 @@ import bpy import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.context +import ifcopenshell.api.root +import ifcopenshell.api.unit import ifcsverchok.helper import ifcsverchok.helper as helper from sverchok.node_tree import SverchCustomTreeNode @@ -59,12 +62,11 @@ class SvIfcCreateProject(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helpe def process_ifc(self, file: ifcopenshell.file, project_name: str) -> None: # create project - project = ifcopenshell.api.run("root.create_entity", file, ifc_class="IfcProject", name=str(project_name)) - lengthunit = ifcopenshell.api.run("unit.add_si_unit", file, unit_type="LENGTHUNIT") - ifcopenshell.api.run("unit.assign_unit", file, units=[lengthunit]) - model = ifcopenshell.api.run("context.add_context", file, context_type="Model") - context = ifcopenshell.api.run( - "context.add_context", + project = ifcopenshell.api.root.create_entity(file, ifc_class="IfcProject", name=str(project_name)) + lengthunit = ifcopenshell.api.unit.add_si_unit(file, unit_type="LENGTHUNIT") + ifcopenshell.api.unit.assign_unit(file, units=[lengthunit]) + model = ifcopenshell.api.context.add_context(file, context_type="Model") + context = ifcopenshell.api.context.add_context( file, context_type="Model", context_identifier="Body", diff --git a/src/ifcsverchok/nodes/ifc/write_file.py b/src/ifcsverchok/nodes/ifc/write_file.py index b277ccadf3..245c8a9d62 100644 --- a/src/ifcsverchok/nodes/ifc/write_file.py +++ b/src/ifcsverchok/nodes/ifc/write_file.py @@ -20,6 +20,9 @@ from os.path import abspath, splitext import bpy import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.aggregate +import ifcopenshell.api.root +import ifcopenshell.api.spatial import ifcopenshell.util.element import ifcsverchok.helper import ifcsverchok.helper as helper @@ -96,7 +99,7 @@ class SvIfcWriteFile(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.Sv # TODO: same code as ifc.write_file_panel? elements_in_buildings = [] if not 0 <= 0 < len(file.by_type("IfcBuilding")): - my_building = ifcopenshell.api.run("root.create_entity", file, ifc_class="IfcBuilding", name="My Building") + my_building = ifcopenshell.api.root.create_entity(file, ifc_class="IfcBuilding", name="My Building") elements = ifcopenshell.util.element.get_decomposition(my_building) else: for building in file.by_type("IfcBuilding"): @@ -106,8 +109,7 @@ class SvIfcWriteFile(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.Sv for spatial in file.by_type("IfcSpatialElement") or file.by_type("IfcSpatialStructureElement"): if not (spatial.is_a("IfcSite") or spatial.is_a("IfcBuilding")) and (spatial not in elements_in_buildings): elements = ifcopenshell.util.element.get_decomposition(spatial) - ifcopenshell.api.run( - "aggregate.assign_object", + ifcopenshell.api.aggregate.assign_object( file, products=[spatial], relating_object=file.by_type("IfcBuilding")[0], @@ -121,8 +123,7 @@ class SvIfcWriteFile(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.Sv elements = file.by_type("IfcElement") for element in elements: if element not in elements_in_buildings: - ifcopenshell.api.run( - "spatial.assign_container", + ifcopenshell.api.spatial.assign_container( file, products=[element], relating_structure=file.by_type("IfcBuilding")[0], @@ -132,9 +133,8 @@ class SvIfcWriteFile(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.Sv elements = ifcopenshell.util.element.get_decomposition(building) if not building.Decomposes: if not 0 <= 0 < len(file.by_type("IfcSite")): - ifcopenshell.api.run("root.create_entity", file, ifc_class="IfcSite", name="My Site") - ifcopenshell.api.run( - "aggregate.assign_object", + ifcopenshell.api.root.create_entity(file, ifc_class="IfcSite", name="My Site") + ifcopenshell.api.aggregate.assign_object( file, products=[building], relating_object=file.by_type("IfcSite")[0], @@ -144,8 +144,7 @@ class SvIfcWriteFile(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.Sv continue except IndexError: pass - ifcopenshell.api.run( - "aggregate.assign_object", + ifcopenshell.api.aggregate.assign_object( file, products=[file.by_type("IfcSite")[0]], relating_object=file.by_type("IfcProject")[0], diff --git a/src/ifctester/test/ids_doc_generator.py b/src/ifctester/test/ids_doc_generator.py index bb518736db..fa95854d35 100644 --- a/src/ifctester/test/ids_doc_generator.py +++ b/src/ifctester/test/ids_doc_generator.py @@ -23,6 +23,14 @@ import pytest import functools import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.aggregate +import ifcopenshell.api.context +import ifcopenshell.api.geometry +import ifcopenshell.api.pset +import ifcopenshell.api.root +import ifcopenshell.api.spatial +import ifcopenshell.api.type +import ifcopenshell.api.unit import ifcopenshell.guid import ifctester import test_facet @@ -303,13 +311,12 @@ specs.to_xml(str(ids_path)) # Create sample model model = ifcopenshell.file() -project = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcProject", name="My Project") +project = ifcopenshell.api.root.create_entity(model, ifc_class="IfcProject", name="My Project") project.Name = "TEST" -ifcopenshell.api.run("unit.assign_unit", model) +ifcopenshell.api.unit.assign_unit(model) -context = ifcopenshell.api.run("context.add_context", model, context_type="Model") -body = ifcopenshell.api.run( - "context.add_context", +context = ifcopenshell.api.context.add_context(model, context_type="Model") +body = ifcopenshell.api.context.add_context( model, context_type="Model", context_identifier="Body", @@ -317,37 +324,37 @@ body = ifcopenshell.api.run( parent=context, ) -site = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcSite", name="My Site") -building = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcBuilding", name="Building A") -storey = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcBuildingStorey", name="Ground Floor") +site = ifcopenshell.api.root.create_entity(model, ifc_class="IfcSite", name="My Site") +building = ifcopenshell.api.root.create_entity(model, ifc_class="IfcBuilding", name="Building A") +storey = ifcopenshell.api.root.create_entity(model, ifc_class="IfcBuildingStorey", name="Ground Floor") -ifcopenshell.api.run("aggregate.assign_object", model, relating_object=project, products=[site]) -ifcopenshell.api.run("aggregate.assign_object", model, relating_object=site, products=[building]) -ifcopenshell.api.run("aggregate.assign_object", model, relating_object=building, products=[storey]) +ifcopenshell.api.aggregate.assign_object(model, relating_object=project, products=[site]) +ifcopenshell.api.aggregate.assign_object(model, relating_object=site, products=[building]) +ifcopenshell.api.aggregate.assign_object(model, relating_object=building, products=[storey]) wall_types = [] for i in range(0, 4): - wall_type = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWallType", name=f"DEMO{i + 1}") - wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall", name=f"WALL {i + 1}") - ifcopenshell.api.run("type.assign_type", model, related_objects=[wall], relating_type=wall_type) - representation = ifcopenshell.api.run( - "geometry.add_wall_representation", model, context=body, length=5, height=3, thickness=(i + 1) * 0.05 + wall_type = ifcopenshell.api.root.create_entity(model, ifc_class="IfcWallType", name=f"DEMO{i + 1}") + wall = ifcopenshell.api.root.create_entity(model, ifc_class="IfcWall", name=f"WALL {i + 1}") + ifcopenshell.api.type.assign_type(model, related_objects=[wall], relating_type=wall_type) + representation = ifcopenshell.api.geometry.add_wall_representation( + model, context=body, length=5, height=3, thickness=(i + 1) * 0.05 ) if i == 0: pass elif i == 1: - pset = ifcopenshell.api.run("pset.add_pset", model, product=wall_type, name="Pset_WallCommon") - ifcopenshell.api.run("pset.edit_pset", model, pset=pset, properties={"FireRating": "-/-/-"}) + pset = ifcopenshell.api.pset.add_pset(model, product=wall_type, name="Pset_WallCommon") + ifcopenshell.api.pset.edit_pset(model, pset=pset, properties={"FireRating": "-/-/-"}) elif i == 2: - pset = ifcopenshell.api.run("pset.add_pset", model, product=wall_type, name="Pset_WallCommon") - ifcopenshell.api.run("pset.edit_pset", model, pset=pset, properties={"FireRating": "120/120/120"}) + pset = ifcopenshell.api.pset.add_pset(model, product=wall_type, name="Pset_WallCommon") + ifcopenshell.api.pset.edit_pset(model, pset=pset, properties={"FireRating": "120/120/120"}) elif i == 3: - pset = ifcopenshell.api.run("pset.add_pset", model, product=wall_type, name="Pset_WallCommon") - ifcopenshell.api.run("pset.edit_pset", model, pset=pset, properties={"FireRating": "FOOBAR"}) - ifcopenshell.api.run("geometry.assign_representation", model, product=wall, representation=representation) + pset = ifcopenshell.api.pset.add_pset(model, product=wall_type, name="Pset_WallCommon") + ifcopenshell.api.pset.edit_pset(model, pset=pset, properties={"FireRating": "FOOBAR"}) + ifcopenshell.api.geometry.assign_representation(model, product=wall, representation=representation) location = np.eye(4) location[1][3] += i * 1 - ifcopenshell.api.run("geometry.edit_object_placement", model, product=wall, matrix=location) - ifcopenshell.api.run("spatial.assign_container", model, relating_structure=storey, products=[wall]) + ifcopenshell.api.geometry.edit_object_placement(model, product=wall, matrix=location) + ifcopenshell.api.spatial.assign_container(model, relating_structure=storey, products=[wall]) model.write(os.path.join(outdir, "library", "sample.ifc")) diff --git a/src/ifctester/test/test_facet.py b/src/ifctester/test/test_facet.py index 3262559a2c..c14a7853c2 100644 --- a/src/ifctester/test/test_facet.py +++ b/src/ifctester/test/test_facet.py @@ -20,7 +20,18 @@ import uuid import ifcopenshell import ifcopenshell.api +import ifcopenshell.api.aggregate +import ifcopenshell.api.classification +import ifcopenshell.api.group +import ifcopenshell.api.material +import ifcopenshell.api.nest +import ifcopenshell.api.pset +import ifcopenshell.api.root +import ifcopenshell.api.spatial +import ifcopenshell.api.type +import ifcopenshell.api.unit import ifcopenshell.guid +import ifcopenshell.util.pset import ifctester.facet from ifctester.facet import Entity, Attribute, Classification, Property, PartOf, Material, Restriction @@ -167,18 +178,16 @@ class TestEntity: ) ifc = ifcopenshell.file() - wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType", predefined_type="X") - ifcopenshell.api.run("type.assign_type", ifc, related_objects=[wall], relating_type=wall_type) + wall = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + wall_type = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWallType", predefined_type="X") + ifcopenshell.api.type.assign_type(ifc, related_objects=[wall], relating_type=wall_type) facet = Entity(name="IFCWALL", predefinedType="X") run("Inherited predefined types should pass", facet=facet, inst=wall, expected=True) ifc = ifcopenshell.file() - wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall", predefined_type="X") - wall_type = ifcopenshell.api.run( - "root.create_entity", ifc, ifc_class="IfcWallType", predefined_type="NOTDEFINED" - ) - ifcopenshell.api.run("type.assign_type", ifc, related_objects=[wall], relating_type=wall_type) + wall = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall", predefined_type="X") + wall_type = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWallType", predefined_type="NOTDEFINED") + ifcopenshell.api.type.assign_type(ifc, related_objects=[wall], relating_type=wall_type) facet = Entity(name="IFCWALL", predefinedType="X") run("Overridden predefined types should pass", facet=facet, inst=wall, expected=True) @@ -211,13 +220,13 @@ class TestEntity: restriction = Restriction(options={"pattern": "FOO.*"}) facet = Entity(name="IFCWALL", predefinedType=restriction) ifc = ifcopenshell.file() - wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall", predefined_type="FOOBAR") + wall = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall", predefined_type="FOOBAR") run("Restrictions an be specified for the predefined type 1/3", facet=facet, inst=wall, expected=True) ifc = ifcopenshell.file() - wall2 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall", predefined_type="FOOBAZ") + wall2 = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall", predefined_type="FOOBAZ") run("Restrictions an be specified for the predefined type 2/3", facet=facet, inst=wall2, expected=True) ifc = ifcopenshell.file() - wall3 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall", predefined_type="BAZFOO") + wall3 = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall", predefined_type="BAZFOO") run("Restrictions an be specified for the predefined type 3/3", facet=facet, inst=wall3, expected=False) @@ -651,9 +660,9 @@ class TestAttribute: run("Value restrictions may be used 3/3", facet=facet, inst=ifc.createIfcWall(Name="Foobar"), expected=False) ifc = ifcopenshell.file() - wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType") - ifcopenshell.api.run("type.assign_type", ifc, related_objects=[wall], relating_type=wall_type) + wall = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + wall_type = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWallType") + ifcopenshell.api.type.assign_type(ifc, related_objects=[wall], relating_type=wall_type) wall_type.Description = "Foobar" facet = Attribute(name="Description", value="Foobar") run("Attributes are not inherited by the occurrence", facet=facet, inst=wall, expected=False) @@ -718,19 +727,16 @@ class TestClassification: ifc = ifcopenshell.file() project = ifc.createIfcProject() - system_a = ifcopenshell.api.run("classification.add_classification", ifc, classification=system_a) - element0 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - element1 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcSlab") - ifcopenshell.api.run( - "classification.add_reference", ifc, products=[element1], reference=ref1, classification=system_a + system_a = ifcopenshell.api.classification.add_classification(ifc, classification=system_a) + element0 = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + element1 = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcSlab") + ifcopenshell.api.classification.add_reference(ifc, products=[element1], reference=ref1, classification=system_a) + element11 = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcColumn") + ifcopenshell.api.classification.add_reference( + ifc, products=[element11], reference=ref11, classification=system_a ) - element11 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcColumn") - ifcopenshell.api.run( - "classification.add_reference", ifc, products=[element11], reference=ref11, classification=system_a - ) - element22 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcBeam") - ifcopenshell.api.run( - "classification.add_reference", + element22 = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcBeam") + ifcopenshell.api.classification.add_reference( ifc, products=[element22], reference=ref22, @@ -738,9 +744,7 @@ class TestClassification: is_lightweight=False, ) material = ifc.createIfcMaterial(Name="Material") - ifcopenshell.api.run( - "classification.add_reference", ifc, products=[material], reference=ref1, classification=system_a - ) + ifcopenshell.api.classification.add_reference(ifc, products=[material], reference=ref1, classification=system_a) facet = Classification(system="Foobar") run( @@ -832,19 +836,17 @@ class TestClassification: # IFC doesn't yet formally specify how inheritance and overrides work here. We follow these rules: # https://github.com/buildingSMART/IFC4.3.x-development/issues/475 - wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType") - ifcopenshell.api.run("type.assign_type", ifc, related_objects=[wall], relating_type=wall_type) - ifcopenshell.api.run( - "classification.add_reference", ifc, products=[wall], reference=ref11, classification=system_a - ) - ifcopenshell.api.run( - "classification.add_reference", ifc, products=[wall_type], reference=ref22, classification=system_a + wall = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + wall_type = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWallType") + ifcopenshell.api.type.assign_type(ifc, related_objects=[wall], relating_type=wall_type) + ifcopenshell.api.classification.add_reference(ifc, products=[wall], reference=ref11, classification=system_a) + ifcopenshell.api.classification.add_reference( + ifc, products=[wall_type], reference=ref22, classification=system_a ) - system_b = ifcopenshell.api.run("classification.add_classification", ifc, classification=system_b) - ifcopenshell.api.run( - "classification.add_reference", ifc, products=[wall_type], reference=refx, classification=system_b + system_b = ifcopenshell.api.classification.add_classification(ifc, classification=system_b) + ifcopenshell.api.classification.add_reference( + ifc, products=[wall_type], reference=refx, classification=system_b ) facet = Classification(system="Foobar", value="11") @@ -888,21 +890,21 @@ class TestProperty: ifc = self.setup_ifc() facet = Property(propertySet="Foo_Bar", baseName="Foo", dataType="IFCLABEL") - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") run("Elements with no properties always fail", facet=facet, inst=element, expected=False) - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"AnotherProperty": "AnotherValue"}) + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="Foo_Bar") + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"AnotherProperty": "AnotherValue"}) run("Elements with a matching pset but no property also fail", facet=facet, inst=element, expected=False) - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"AnotherProperty": None}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"AnotherProperty": None}) run("Properties with a null value fail", facet=facet, inst=element, expected=False) - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": "Bar"}) run("A name check will match any property with any string value", facet=facet, inst=element, expected=True) ifc = self.setup_ifc() facet = Property(propertySet="Foo_Bar", baseName="Foo", dataType="IFCLABEL") - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"}) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="Foo_Bar") + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": "Bar"}) run("A required facet checks all parameters as normal", facet=facet, inst=element, expected=True) facet = Property(propertySet="Foo_Bar", baseName="Foo", dataType="IFCLABEL", cardinality="prohibited") run("A prohibited facet returns the opposite of a required facet", facet=facet, inst=element, expected=False) @@ -921,19 +923,19 @@ class TestProperty: expected=True, ) - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ""}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ""}) facet = Property(propertySet="Foo_Bar", baseName="Foo", dataType="IFCLABEL") run("An empty string is considered falsey and will not pass", facet=facet, inst=element, expected=False) - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcLogical("UNKNOWN")}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcLogical("UNKNOWN")}) facet = Property(propertySet="Foo_Bar", baseName="Foo", dataType="IFCLOGICAL") run("A logical unknown is considered falsey and will not pass", facet=facet, inst=element, expected=False) - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcDuration("P0D")}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcDuration("P0D")}) facet = Property(propertySet="Foo_Bar", baseName="Foo", dataType="IFCDURATION") run("A zero duration will pass", facet=facet, inst=element, expected=True) facet = Property(propertySet="Foo_Bar", baseName="Foo", dataType="IFCBOOLEAN") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcBoolean(True)}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcBoolean(True)}) run("A property set to true will pass a name check", facet=facet, inst=element, expected=True) - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": False}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": False}) run( "A property set to false is still considered a value and will pass a name check", facet=facet, @@ -943,35 +945,35 @@ class TestProperty: ifc = self.setup_ifc() facet = Property(propertySet="Foo_Bar", baseName="Foo", value="Bar", dataType="IFCLABEL") - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"}) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="Foo_Bar") + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": "Bar"}) run("Specifying a value performs a case-sensitive match 1/2", facet=facet, inst=element, expected=True) - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "bar"}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": "bar"}) run("Specifying a value performs a case-sensitive match 2/2", facet=facet, inst=element, expected=False) - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Baz"}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": "Baz"}) run("Specifying a value fails against different values", facet=facet, inst=element, expected=False) facet = Property(propertySet="Foo_Bar", baseName="Foo", value="♫Don'tÄrgerhôtelЊет", dataType="IFCLABEL") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "♫Don'tÄrgerhôtelЊет"}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": "♫Don'tÄrgerhôtelЊет"}) run("Non-ascii characters are treated without encoding", facet=facet, inst=element, expected=True) identifier = "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345" facet = Property( propertySet="Foo_Bar", baseName="Foo", value=identifier + "_extra_characters", dataType="IFCIDENTIFIER" ) - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcIdentifier(identifier)}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcIdentifier(identifier)}) run("IDS does not handle string truncation such as for identifiers", facet=facet, inst=element, expected=False) ifc = self.setup_ifc() facet = Property(propertySet="Foo_Bar", baseName="Foo", value="1", dataType="IFCLABEL") - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "1"}) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="Foo_Bar") + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": "1"}) run("A number specified as a string is treated as a string", facet=facet, inst=element, expected=True) facet = Property(propertySet="Foo_Bar", baseName="Foo", value="42", dataType="IFCINTEGER") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcInteger(42)}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcInteger(42)}) run("Integer values are checked using type casting 1/4", facet=facet, inst=element, expected=True) facet = Property(propertySet="Foo_Bar", baseName="Foo", value="42.", dataType="IFCINTEGER") run("Integer values are checked using type casting 2/4", facet=facet, inst=element, expected=True) @@ -981,19 +983,19 @@ class TestProperty: run("Integer values are checked using type casting 4/4", facet=facet, inst=element, expected=False) facet = Property(propertySet="Foo_Bar", baseName="Foo", value="42", dataType="IFCREAL") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42.0)}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42.0)}) run("Real values are checked using type casting 1/3", facet=facet, inst=element, expected=True) facet = Property(propertySet="Foo_Bar", baseName="Foo", value="42.0", dataType="IFCREAL") run("Real values are checked using type casting 2/3", facet=facet, inst=element, expected=True) facet = Property(propertySet="Foo_Bar", baseName="Foo", value="42.3", dataType="IFCREAL") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42.3)}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42.3)}) run("Real values are checked using type casting 3/3", facet=facet, inst=element, expected=True) facet = Property(propertySet="Foo_Bar", baseName="Foo", value="42,3", dataType="IFCREAL") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42.3)}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42.3)}) run("Only specifically formatted numbers are allowed 1/4", facet=facet, inst=element, expected=False) facet = Property(propertySet="Foo_Bar", baseName="Foo", value="123,4.5", dataType="IFCREAL") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcReal(1234.5)}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcReal(1234.5)}) run("Only specifically formatted numbers are allowed 2/4", facet=facet, inst=element, expected=False) facet = Property(propertySet="Foo_Bar", baseName="Foo", value="1.2345e3", dataType="IFCREAL") run("Only specifically formatted numbers are allowed 3/4", facet=facet, inst=element, expected=True) @@ -1001,25 +1003,17 @@ class TestProperty: run("Only specifically formatted numbers are allowed 4/4", facet=facet, inst=element, expected=True) facet = Property(propertySet="Foo_Bar", baseName="Foo", value="42.", dataType="IFCREAL") - ifcopenshell.api.run( - "pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42.0 * (1.0 + 1e-6))} - ) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42.0 * (1.0 + 1e-6))}) run("Floating point numbers are compared with a 1e-6 tolerance 1/4", facet=facet, inst=element, expected=True) - ifcopenshell.api.run( - "pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42.0 * (1.0 - 1e-6))} - ) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42.0 * (1.0 - 1e-6))}) run("Floating point numbers are compared with a 1e-6 tolerance 2/4", facet=facet, inst=element, expected=True) - ifcopenshell.api.run( - "pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42.0 * (1.0 + 2e-6))} - ) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42.0 * (1.0 + 2e-6))}) run("Floating point numbers are compared with a 1e-6 tolerance 3/4", facet=facet, inst=element, expected=False) - ifcopenshell.api.run( - "pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42.0 * (1.0 - 2e-6))} - ) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42.0 * (1.0 - 2e-6))}) run("Floating point numbers are compared with a 1e-6 tolerance 4/4", facet=facet, inst=element, expected=False) facet = Property(propertySet="Foo_Bar", baseName="Foo", value="true", dataType="IFCBOOLEAN") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcBoolean(False)}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcBoolean(False)}) run("Booleans must be specified as uppercase strings 1/3", facet=facet, inst=element, expected=False) facet = Property(propertySet="Foo_Bar", baseName="Foo", value="false", dataType="IFCBOOLEAN") run("Booleans must be specified as uppercase strings 2/3", facet=facet, inst=element, expected=True) @@ -1032,25 +1026,22 @@ class TestProperty: run("Booleans can be specified as as a 0 or 1 2/2", facet=facet, inst=element, expected=False) facet = Property(propertySet="Foo_Bar", baseName="Foo", value="2022-01-01", dataType="IFCDATE") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcDate("2022-01-01")}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcDate("2022-01-01")}) run("Dates are treated as strings 1/2", facet=facet, inst=element, expected=True) - ifcopenshell.api.run( - "pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcDate("2022-01-01+00:00")} - ) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcDate("2022-01-01+00:00")}) run("Dates are treated as strings 2/2", facet=facet, inst=element, expected=False) facet = Property(propertySet="Foo_Bar", baseName="Foo", value="PT16H", dataType="IFCDURATION") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcDuration("PT16H")}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcDuration("PT16H")}) run("Durations are treated as strings 1/2", facet=facet, inst=element, expected=True) - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcDuration("P2D")}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcDuration("P2D")}) run("Durations are treated as strings 1/2", facet=facet, inst=element, expected=False) ifc = self.setup_ifc() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Pset_WallCommon") + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="Pset_WallCommon") pset_template = ifcopenshell.util.pset.get_template("IFC4").get_by_name("Pset_WallCommon") - ifcopenshell.api.run( - "pset.edit_pset", + ifcopenshell.api.pset.edit_pset( ifc, pset=pset, properties={"Status": ["EXISTING", "DEMOLISH"]}, @@ -1064,8 +1055,8 @@ class TestProperty: run("Any matching value in an enumerated property will pass 3/3", facet=facet, inst=element, expected=False) ifc = self.setup_ifc() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar") + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="Foo_Bar") list_property = ifc.createIfcPropertyListValue( Name="Foo", ListValues=[ifc.createIfcLabel("X"), ifc.createIfcLabel("Y")] ) @@ -1078,8 +1069,8 @@ class TestProperty: run("Any matching value in a list property will pass 3/3", facet=facet, inst=element, expected=False) ifc = self.setup_ifc() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar") + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="Foo_Bar") bounded_property = ifc.createIfcPropertyBoundedValue( Name="Foo", UpperBoundValue=ifc.createIfcLengthMeasure(5000), @@ -1097,8 +1088,8 @@ class TestProperty: run("Any matching value in a bounded property will pass 4/4", facet=facet, inst=element, expected=False) ifc = self.setup_ifc() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar") + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="Foo_Bar") table_property = ifc.createIfcPropertyTableValue( Name="Foo", DefiningValues=[ifc.createIfcLabel("X")], DefinedValues=[ifc.createIfcLengthMeasure(1000)] ) @@ -1111,14 +1102,14 @@ class TestProperty: run("Any matching value in a table property will pass 3/3", facet=facet, inst=element, expected=False) ifc = self.setup_ifc() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar") + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="Foo_Bar") pset.HasProperties = [ifc.createIfcPropertyReferenceValue(Name="Foo")] facet = Property(propertySet="Foo_Bar", baseName="Foo", dataType="IFCLABEL") run("Reference properties are treated as objects and not supported", facet=facet, inst=element, expected=False) ifc = self.setup_ifc() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcDoor") + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcDoor") pset = ifc.create_entity( "IfcDoorPanelProperties", GlobalId=ifcopenshell.guid.new(), @@ -1143,18 +1134,18 @@ class TestProperty: ifc = self.setup_ifc() facet = Property(propertySet="Foo_Bar", baseName="Foo", dataType="IFCLENGTHMEASURE") - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - qto = ifcopenshell.api.run("pset.add_qto", ifc, product=element, name="Foo_Bar") - ifcopenshell.api.run("pset.edit_qto", ifc, qto=qto, properties={"Foo": ifc.createIfcLengthMeasure(42)}) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + qto = ifcopenshell.api.pset.add_qto(ifc, product=element, name="Foo_Bar") + ifcopenshell.api.pset.edit_qto(ifc, qto=qto, properties={"Foo": ifc.createIfcLengthMeasure(42)}) run("A name check will match any quantity with any value", facet=facet, inst=element, expected=True) facet = Property(propertySet="Foo_Bar", baseName="Foo", dataType="IFCAREAMEASURE") run("Quantities must also match the appropriate measure", facet=facet, inst=element, expected=False) ifc = self.setup_ifc() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar") + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="Foo_Bar") complex_property = ifc.createIfcComplexProperty(Name="Foo", UsageName="RabbitAgilityTraining") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=complex_property, properties={"Rabbits": "Awesome"}) + ifcopenshell.api.pset.edit_pset(ifc, pset=complex_property, properties={"Rabbits": "Awesome"}) pset.HasProperties = [complex_property] facet = Property(propertySet="Foo_Bar", baseName="Foo", dataType="IFCLABEL") run("Complex properties are not supported 1/2", facet=facet, inst=element, expected=False) @@ -1162,11 +1153,11 @@ class TestProperty: run("Complex properties are not supported 2/2", facet=facet, inst=element, expected=False) ifc = self.setup_ifc() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - qto = ifcopenshell.api.run("pset.add_qto", ifc, product=element, name="Foo_Bar") + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + qto = ifcopenshell.api.pset.add_qto(ifc, product=element, name="Foo_Bar") complex_quantity = ifc.createIfcPhysicalComplexQuantity(Name="Foo", Discrimination="FurThickness") - ifcopenshell.api.run( - "pset.edit_qto", ifc, qto=complex_quantity, properties={"MyLength": ifc.createIfcLengthMeasure(42)} + ifcopenshell.api.pset.edit_qto( + ifc, qto=complex_quantity, properties={"MyLength": ifc.createIfcLengthMeasure(42)} ) qto.Quantities = [complex_quantity] facet = Property(propertySet="Foo_Bar", baseName="Foo", dataType="IFCLENGTHMEASURE") @@ -1177,42 +1168,42 @@ class TestProperty: ifc = self.setup_ifc() restriction = Restriction(options={"pattern": "Foo_.*"}) facet = Property(propertySet=restriction, baseName="Foo", dataType="IFCLABEL") - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"}) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="Foo_Bar") + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": "Bar"}) run("All matching property sets must satisfy requirements 1/3", facet=facet, inst=element, expected=True) - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Baz") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"AnotherProperty": "AnotherValue"}) + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="Foo_Baz") + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"AnotherProperty": "AnotherValue"}) run("All matching property sets must satisfy requirements 2/3", facet=facet, inst=element, expected=False) - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": "Bar"}) run("All matching property sets must satisfy requirements 3/3", facet=facet, inst=element, expected=True) ifc = self.setup_ifc() restriction = Restriction(options={"pattern": "Foo.*"}) facet = Property(propertySet="Foo_Bar", baseName=restriction, value="x", dataType="IFCLABEL") - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foobar": "x"}) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="Foo_Bar") + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foobar": "x"}) run("All matching properties must satisfy requirements 1/3", facet=facet, inst=element, expected=True) - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foobar": "x", "Foobaz": "x"}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foobar": "x", "Foobaz": "x"}) run("All matching properties must satisfy requirements 2/3", facet=facet, inst=element, expected=True) - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foobar": "x", "Foobaz": "y"}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foobar": "x", "Foobaz": "y"}) run("All matching properties must satisfy requirements 3/3", facet=facet, inst=element, expected=False) ifc = self.setup_ifc() restriction1 = Restriction(options={"pattern": "Foo.*"}) restriction2 = Restriction(options={"enumeration": ["x", "y"]}) facet = Property(propertySet="Foo_Bar", baseName=restriction1, value=restriction2, dataType="IFCLABEL") - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foobar": "x", "Foobaz": "y"}) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="Foo_Bar") + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foobar": "x", "Foobaz": "y"}) run( "If multiple properties are matched, all values must satisfy requirements 1/2", facet=facet, inst=element, expected=True, ) - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foobar": "x", "Foobaz": "z"}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foobar": "x", "Foobaz": "z"}) run( "If multiple properties are matched, all values must satisfy requirements 2/2", facet=facet, @@ -1222,25 +1213,25 @@ class TestProperty: ifc = self.setup_ifc() facet = Property(propertySet="Foo_Bar", baseName="Foo", value="2", dataType="IFCTIMEMEASURE") - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcMassMeasure(2)}) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="Foo_Bar") + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcMassMeasure(2)}) run("Measures are used to specify an IFC data type 1/2", facet=facet, inst=element, expected=False) - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcTimeMeasure(2)}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcTimeMeasure(2)}) run("Measures are used to specify an IFC data type 2/2", facet=facet, inst=element, expected=True) ifc = self.setup_ifc() facet = Property(propertySet="Foo_Bar", baseName="Foo", value="2", dataType="IFCLENGTHMEASURE") - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcLengthMeasure(2)}) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + pset = ifcopenshell.api.pset.add_pset(ifc, product=element, name="Foo_Bar") + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcLengthMeasure(2)}) run( "Unit conversions shall take place to IDS-nominated standard units 1/2", facet=facet, inst=element, expected=False, ) - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcLengthMeasure(2000)}) + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": ifc.createIfcLengthMeasure(2000)}) run( "Unit conversions shall take place to IDS-nominated standard units 2/2", facet=facet, @@ -1249,23 +1240,23 @@ class TestProperty: ) ifc = self.setup_ifc() - wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType") - ifcopenshell.api.run("type.assign_type", ifc, related_objects=[wall], relating_type=wall_type) - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=wall_type, name="Foo_Bar") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"}) + wall = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + wall_type = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWallType") + ifcopenshell.api.type.assign_type(ifc, related_objects=[wall], relating_type=wall_type) + pset = ifcopenshell.api.pset.add_pset(ifc, product=wall_type, name="Foo_Bar") + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": "Bar"}) facet = Property(propertySet="Foo_Bar", baseName="Foo", dataType="IFCLABEL") run("Properties can be inherited from the type 1/2", facet=facet, inst=wall, expected=True) run("Properties can be inherited from the type 2/2", facet=facet, inst=wall_type, expected=True) ifc = self.setup_ifc() - wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType") - ifcopenshell.api.run("type.assign_type", ifc, related_objects=[wall], relating_type=wall_type) - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=wall_type, name="Foo_Bar") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Baz"}) - pset = ifcopenshell.api.run("pset.add_pset", ifc, product=wall, name="Foo_Bar") - ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"}) + wall = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + wall_type = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWallType") + ifcopenshell.api.type.assign_type(ifc, related_objects=[wall], relating_type=wall_type) + pset = ifcopenshell.api.pset.add_pset(ifc, product=wall_type, name="Foo_Bar") + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": "Baz"}) + pset = ifcopenshell.api.pset.add_pset(ifc, product=wall, name="Foo_Bar") + ifcopenshell.api.pset.edit_pset(ifc, pset=pset, properties={"Foo": "Bar"}) facet = Property(propertySet="Foo_Bar", baseName="Foo", value="Bar", dataType="IFCLABEL") run("Properties can be overriden by an occurrence 1/2", facet=facet, inst=wall, expected=True) run("Properties can be overriden by an occurrence 2/2", facet=facet, inst=wall_type, expected=False) @@ -1274,11 +1265,11 @@ class TestProperty: ifc = ifcopenshell.file() ifc.createIfcProject() # Milli prefix used to check measurement conversions - lengthunit = ifcopenshell.api.run("unit.add_si_unit", ifc, unit_type="LENGTHUNIT", prefix="MILLI") - areaunit = ifcopenshell.api.run("unit.add_si_unit", ifc, unit_type="AREAUNIT", prefix="MILLI") - volumeunit = ifcopenshell.api.run("unit.add_si_unit", ifc, unit_type="VOLUMEUNIT", prefix="MILLI") - timeunit = ifcopenshell.api.run("unit.add_si_unit", ifc, unit_type="TIMEUNIT") - ifcopenshell.api.run("unit.assign_unit", ifc, units=[lengthunit, areaunit, volumeunit, timeunit]) + lengthunit = ifcopenshell.api.unit.add_si_unit(ifc, unit_type="LENGTHUNIT", prefix="MILLI") + areaunit = ifcopenshell.api.unit.add_si_unit(ifc, unit_type="AREAUNIT", prefix="MILLI") + volumeunit = ifcopenshell.api.unit.add_si_unit(ifc, unit_type="VOLUMEUNIT", prefix="MILLI") + timeunit = ifcopenshell.api.unit.add_si_unit(ifc, unit_type="TIMEUNIT") + ifcopenshell.api.unit.assign_unit(ifc, units=[lengthunit, areaunit, volumeunit, timeunit]) return ifc @@ -1299,10 +1290,10 @@ class TestMaterial: facet = Material() ifc = ifcopenshell.file() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") run("Elements without a material always fail", facet=facet, inst=element, expected=False) - material = ifcopenshell.api.run("material.add_material", ifc) - ifcopenshell.api.run("material.assign_material", ifc, products=[element], material=material) + material = ifcopenshell.api.material.add_material(ifc) + ifcopenshell.api.material.assign_material(ifc, products=[element], material=material) run("Elements with any material will pass an empty material facet", facet=facet, inst=element, expected=True) run("A required facet checks all parameters as normal", facet=facet, inst=element, expected=True) @@ -1325,9 +1316,9 @@ class TestMaterial: ifc = ifcopenshell.file() facet = Material(value="Foo") - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - material = ifcopenshell.api.run("material.add_material", ifc) - ifcopenshell.api.run("material.assign_material", ifc, products=[element], material=material) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + material = ifcopenshell.api.material.add_material(ifc) + ifcopenshell.api.material.assign_material(ifc, products=[element], material=material) material.Name = "Foo" run("A material name may pass the value check", facet=facet, inst=element, expected=True) material.Name = "Bar" @@ -1336,11 +1327,11 @@ class TestMaterial: ifc = ifcopenshell.file() facet = Material(value="Foo") - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - material_set = ifcopenshell.api.run("material.add_material_set", ifc, set_type="IfcMaterialList") - ifcopenshell.api.run("material.assign_material", ifc, products=[element], material=material_set) - material = ifcopenshell.api.run("material.add_material", ifc) - ifcopenshell.api.run("material.add_list_item", ifc, material_list=material_set, material=material) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + material_set = ifcopenshell.api.material.add_material_set(ifc, set_type="IfcMaterialList") + ifcopenshell.api.material.assign_material(ifc, products=[element], material=material_set) + material = ifcopenshell.api.material.add_material(ifc) + ifcopenshell.api.material.add_list_item(ifc, material_list=material_set, material=material) material.Name = "Foo" run("Any material Name in a list will pass a value check", facet=facet, inst=element, expected=True) material.Name = "Bar" @@ -1349,11 +1340,11 @@ class TestMaterial: ifc = ifcopenshell.file() facet = Material(value="Foo") - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - material_set = ifcopenshell.api.run("material.add_material_set", ifc, set_type="IfcMaterialLayerSet") - ifcopenshell.api.run("material.assign_material", ifc, products=[element], material=material_set) - material = ifcopenshell.api.run("material.add_material", ifc) - layer = ifcopenshell.api.run("material.add_layer", ifc, layer_set=material_set, material=material) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + material_set = ifcopenshell.api.material.add_material_set(ifc, set_type="IfcMaterialLayerSet") + ifcopenshell.api.material.assign_material(ifc, products=[element], material=material_set) + material = ifcopenshell.api.material.add_material(ifc) + layer = ifcopenshell.api.material.add_layer(ifc, layer_set=material_set, material=material) layer.Name = "Foo" run("Any layer Name in a layer set will pass a value check", facet=facet, inst=element, expected=True) layer.Name = "Bar" @@ -1368,11 +1359,11 @@ class TestMaterial: ifc = ifcopenshell.file() facet = Material(value="Foo") - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - material_set = ifcopenshell.api.run("material.add_material_set", ifc, set_type="IfcMaterialProfileSet") - ifcopenshell.api.run("material.assign_material", ifc, products=[element], material=material_set) - material = ifcopenshell.api.run("material.add_material", ifc) - profile = ifcopenshell.api.run("material.add_profile", ifc, profile_set=material_set, material=material) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + material_set = ifcopenshell.api.material.add_material_set(ifc, set_type="IfcMaterialProfileSet") + ifcopenshell.api.material.assign_material(ifc, products=[element], material=material_set) + material = ifcopenshell.api.material.add_material(ifc) + profile = ifcopenshell.api.material.add_profile(ifc, profile_set=material_set, material=material) profile.Name = "Foo" profile.Profile = ifc.createIfcCircleProfileDef("AREA", None, None, 1) run("Any profile Name in a profile set will pass a value check", facet=facet, inst=element, expected=True) @@ -1388,14 +1379,12 @@ class TestMaterial: ifc = ifcopenshell.file() facet = Material(value="Foo") - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - material_set = ifcopenshell.api.run("material.add_material_set", ifc, set_type="IfcMaterialConstituentSet") - ifcopenshell.api.run("material.assign_material", ifc, products=[element], material=material_set) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + material_set = ifcopenshell.api.material.add_material_set(ifc, set_type="IfcMaterialConstituentSet") + ifcopenshell.api.material.assign_material(ifc, products=[element], material=material_set) run("A constituent set with no data will fail a value check", facet=facet, inst=element, expected=False) - material = ifcopenshell.api.run("material.add_material", ifc) - constituent = ifcopenshell.api.run( - "material.add_constituent", ifc, constituent_set=material_set, material=material - ) + material = ifcopenshell.api.material.add_material(ifc) + constituent = ifcopenshell.api.material.add_constituent(ifc, constituent_set=material_set, material=material) constituent.Name = "Foo" run( "Any constituent Name in a constituent set will pass a value check", @@ -1424,24 +1413,24 @@ class TestMaterial: ) ifc = ifcopenshell.file() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - element_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType") - ifcopenshell.api.run("type.assign_type", ifc, related_objects=[element], relating_type=element_type) - material = ifcopenshell.api.run("material.add_material", ifc) - ifcopenshell.api.run("material.assign_material", ifc, products=[element_type], material=material) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + element_type = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWallType") + ifcopenshell.api.type.assign_type(ifc, related_objects=[element], relating_type=element_type) + material = ifcopenshell.api.material.add_material(ifc) + ifcopenshell.api.material.assign_material(ifc, products=[element_type], material=material) material.Name = "Foo" facet = Material(value="Foo") run("Occurrences can inherit materials from their types", facet=facet, inst=element, expected=True) ifc = ifcopenshell.file() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") - element_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType") - ifcopenshell.api.run("type.assign_type", ifc, related_objects=[element], relating_type=element_type) - material = ifcopenshell.api.run("material.add_material", ifc) - ifcopenshell.api.run("material.assign_material", ifc, products=[element_type], material=material) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") + element_type = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWallType") + ifcopenshell.api.type.assign_type(ifc, related_objects=[element], relating_type=element_type) + material = ifcopenshell.api.material.add_material(ifc) + ifcopenshell.api.material.assign_material(ifc, products=[element_type], material=material) material.Name = "Bar" - material = ifcopenshell.api.run("material.add_material", ifc) - ifcopenshell.api.run("material.assign_material", ifc, products=[element], material=material) + material = ifcopenshell.api.material.add_material(ifc) + ifcopenshell.api.material.assign_material(ifc, products=[element], material=material) material.Name = "Foo" facet = Material(value="Foo") run("Occurrences can override materials from their types", facet=facet, inst=element, expected=True) @@ -1476,11 +1465,11 @@ class TestPartOf: ifc = ifcopenshell.file() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcElementAssembly") - subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcElementAssembly") + subelement = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall") facet = PartOf(name="IFCELEMENTASSEMBLY", relation="IFCRELAGGREGATES") run("A non aggregated element fails an aggregate relationship", facet=facet, inst=subelement, expected=False) - ifcopenshell.api.run("aggregate.assign_object", ifc, products=[subelement], relating_object=element) + ifcopenshell.api.aggregate.assign_object(ifc, products=[subelement], relating_object=element) run("The aggregated whole fails an aggregate relationship", facet=facet, inst=element, expected=False) run("The aggregated part passes an aggregate relationship", facet=facet, inst=subelement, expected=True) @@ -1489,9 +1478,9 @@ class TestPartOf: run("A prohibited facet returns the opposite of a required facet", facet=facet, inst=subelement, expected=False) ifc = ifcopenshell.file() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcSlab") - subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcBeam") - ifcopenshell.api.run("aggregate.assign_object", ifc, products=[subelement], relating_object=element) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcSlab") + subelement = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcBeam") + ifcopenshell.api.aggregate.assign_object(ifc, products=[subelement], relating_object=element) facet = PartOf(name="IFCSLAB", relation="IFCRELAGGREGATES") run("An aggregate may specify the entity of the whole 1/2", facet=facet, inst=subelement, expected=True) facet = PartOf(name="IFCWALL", relation="IFCRELAGGREGATES") @@ -1511,27 +1500,27 @@ class TestPartOf: ) ifc = ifcopenshell.file() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcElementAssembly") - subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcSlab") - subsubelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcBeam") - ifcopenshell.api.run("aggregate.assign_object", ifc, products=[subelement], relating_object=element) - ifcopenshell.api.run("aggregate.assign_object", ifc, products=[subsubelement], relating_object=subelement) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcElementAssembly") + subelement = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcSlab") + subsubelement = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcBeam") + ifcopenshell.api.aggregate.assign_object(ifc, products=[subelement], relating_object=element) + ifcopenshell.api.aggregate.assign_object(ifc, products=[subsubelement], relating_object=subelement) facet = PartOf(name="IFCELEMENTASSEMBLY", relation="IFCRELAGGREGATES") run("An aggregate entity may pass any ancestral whole passes", facet=facet, inst=subsubelement, expected=True) ifc = ifcopenshell.file() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcElementAssembly") - group = ifcopenshell.api.run("group.add_group", ifc) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcElementAssembly") + group = ifcopenshell.api.group.add_group(ifc) facet = PartOf(name="IFCGROUP", relation="IFCRELASSIGNSTOGROUP") run("A non grouped element fails a group relationship", facet=facet, inst=element, expected=False) - ifcopenshell.api.run("group.assign_group", ifc, products=[element], group=group) + ifcopenshell.api.group.assign_group(ifc, products=[element], group=group) run("A grouped element passes a group relationship", facet=facet, inst=element, expected=True) ifc = ifcopenshell.file() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcElementAssembly") + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcElementAssembly") group = ifc.createIfcInventory() facet = PartOf(name="IFCGROUP", relation="IFCRELASSIGNSTOGROUP") - ifcopenshell.api.run("group.assign_group", ifc, products=[element], group=group) + ifcopenshell.api.group.assign_group(ifc, products=[element], group=group) run("A group entity must match exactly 1/2", facet=facet, inst=element, expected=False) facet = PartOf(name="IFCINVENTORY", relation="IFCRELASSIGNSTOGROUP") run("A group entity must match exactly 2/2", facet=facet, inst=element, expected=True) @@ -1543,18 +1532,18 @@ class TestPartOf: run("A group predefined type must match exactly 2/2", facet=facet, inst=element, expected=True) ifc = ifcopenshell.file() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcElementAssembly") - container = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcSpace") + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcElementAssembly") + container = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcSpace") facet = PartOf(name="IFCSPACE", relation="IFCRELCONTAINEDINSPATIALSTRUCTURE") run("Any contained element passes a containment relationship 1/2", facet=facet, inst=element, expected=False) - ifcopenshell.api.run("spatial.assign_container", ifc, products=[element], relating_structure=container) + ifcopenshell.api.spatial.assign_container(ifc, products=[element], relating_structure=container) run("Any contained element passes a containment relationship 2/2", facet=facet, inst=element, expected=True) run("The container itself always fails", facet=facet, inst=container, expected=False) ifc = ifcopenshell.file() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcElementAssembly") - container = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcSpace") - ifcopenshell.api.run("spatial.assign_container", ifc, products=[element], relating_structure=container) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcElementAssembly") + container = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcSpace") + ifcopenshell.api.spatial.assign_container(ifc, products=[element], relating_structure=container) facet = PartOf(relation="IFCRELCONTAINEDINSPATIALSTRUCTURE", name="IFCSITE") run("The container entity must match exactly 1/2", facet=facet, inst=element, expected=False) facet = PartOf(relation="IFCRELCONTAINEDINSPATIALSTRUCTURE", name="IFCSPACE") @@ -1567,26 +1556,26 @@ class TestPartOf: run("The container predefined type must match exactly 2/2", facet=facet, inst=element, expected=True) ifc = ifcopenshell.file() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcSlab") - subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcBeam") - ifcopenshell.api.run("aggregate.assign_object", ifc, products=[subelement], relating_object=element) - container = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcSpace") - ifcopenshell.api.run("spatial.assign_container", ifc, products=[element], relating_structure=container) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcSlab") + subelement = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcBeam") + ifcopenshell.api.aggregate.assign_object(ifc, products=[subelement], relating_object=element) + container = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcSpace") + ifcopenshell.api.spatial.assign_container(ifc, products=[element], relating_structure=container) facet = PartOf(relation="IFCRELCONTAINEDINSPATIALSTRUCTURE", name="IFCSPACE") run("The container may be indirect", facet=facet, inst=subelement, expected=True) ifc = ifcopenshell.file() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcFurniture") - subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcDiscreteAccessory") - ifcopenshell.api.run("nest.assign_object", ifc, related_objects=[subelement], relating_object=element) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcFurniture") + subelement = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcDiscreteAccessory") + ifcopenshell.api.nest.assign_object(ifc, related_objects=[subelement], relating_object=element) facet = PartOf(name="IFCFURNITURE", relation="IFCRELNESTS") run("Any nested part passes a nest relationship", facet=facet, inst=subelement, expected=True) run("Any nested whole fails a nest relationship", facet=facet, inst=element, expected=False) ifc = ifcopenshell.file() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcFurniture") - subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcDiscreteAccessory") - ifcopenshell.api.run("nest.assign_object", ifc, related_objects=[subelement], relating_object=element) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcFurniture") + subelement = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcDiscreteAccessory") + ifcopenshell.api.nest.assign_object(ifc, related_objects=[subelement], relating_object=element) facet = PartOf(relation="IFCRELNESTS", name="IFCBEAM") run("The nest entity must match exactly 1/2", facet=facet, inst=subelement, expected=False) facet = PartOf(relation="IFCRELNESTS", name="IFCFURNITURE") @@ -1600,11 +1589,11 @@ class TestPartOf: run("The nest predefined type must match exactly 2/2", facet=facet, inst=subelement, expected=True) ifc = ifcopenshell.file() - element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcFurniture") - subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcDiscreteAccessory") - subsubelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcMechanicalFastener") - ifcopenshell.api.run("nest.assign_object", ifc, related_objects=[subelement], relating_object=element) - ifcopenshell.api.run("nest.assign_object", ifc, related_objects=[subsubelement], relating_object=subelement) + element = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcFurniture") + subelement = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcDiscreteAccessory") + subsubelement = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcMechanicalFastener") + ifcopenshell.api.nest.assign_object(ifc, related_objects=[subelement], relating_object=element) + ifcopenshell.api.nest.assign_object(ifc, related_objects=[subsubelement], relating_object=subelement) facet = PartOf(relation="IFCRELNESTS", name="IFCFURNITURE") run("Nesting may be indirect", facet=facet, inst=subsubelement, expected=True) diff --git a/src/ifctester/test/test_ids.py b/src/ifctester/test/test_ids.py index 9751d76952..3763f8159b 100644 --- a/src/ifctester/test/test_ids.py +++ b/src/ifctester/test/test_ids.py @@ -20,6 +20,8 @@ import os import pytest import xmlschema import ifcopenshell +import ifcopenshell.api +import ifcopenshell.api.material from ifctester import ids from typing import Optional