diff --git a/src/blenderbim/blenderbim/bim/module/classification/operator.py b/src/blenderbim/blenderbim/bim/module/classification/operator.py index 08020cef76..fa35886176 100644 --- a/src/blenderbim/blenderbim/bim/module/classification/operator.py +++ b/src/blenderbim/blenderbim/bim/module/classification/operator.py @@ -88,7 +88,7 @@ class AddManualClassificationReference(bpy.types.Operator, tool.Ifc.Operator): reference = ifcopenshell.api.run( "classification.add_reference", tool.Ifc.get(), - product=product, + products=[product], classification=classification, identification="X", name="Unnamed", @@ -358,15 +358,18 @@ class AddClassificationReference(bpy.types.Operator, tool.Ifc.Operator): classification = element break - for obj in objects: - ifc_definition_id = tool.Blender.get_obj_ifc_definition_id(obj, self.obj_type, context) - if not ifc_definition_id: - continue + ifc_file = tool.Ifc.get() + products = [ + ifc_file.by_id(ifc_definition_id) + for obj in objects + if (ifc_definition_id := tool.Blender.get_obj_ifc_definition_id(obj, self.obj_type, context)) + ] + if products: ifcopenshell.api.run( "classification.add_reference", tool.Ifc.get(), reference=IfcStore.classification_file.by_id(self.reference), - product=tool.Ifc.get().by_id(ifc_definition_id), + products=products, classification=classification, ) @@ -414,7 +417,7 @@ class AddClassificationReferenceFromBSDD(bpy.types.Operator, tool.Ifc.Operator): reference = ifcopenshell.api.run( "classification.add_reference", tool.Ifc.get(), - product=element, + products=[element], classification=classification, identification=bsdd_classification.reference_code, name=bsdd_classification.name, diff --git a/src/ifcopenshell-python/ifcopenshell/api/__init__.py b/src/ifcopenshell-python/ifcopenshell/api/__init__.py index 8f7b82351c..7c739cf71b 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/__init__.py +++ b/src/ifcopenshell-python/ifcopenshell/api/__init__.py @@ -87,6 +87,9 @@ ARGUMENTS_DEPRECATION = { "material.unassign_material": partial( batching_argument_deprecation, prev_argument="product", new_argument="products" ), + "classification.add_reference": partial( + batching_argument_deprecation, prev_argument="product", new_argument="products" + ), } diff --git a/src/ifcopenshell-python/ifcopenshell/api/classification/add_reference.py b/src/ifcopenshell-python/ifcopenshell/api/classification/add_reference.py index 320825e335..9057f7a25f 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/classification/add_reference.py +++ b/src/ifcopenshell-python/ifcopenshell/api/classification/add_reference.py @@ -17,12 +17,24 @@ # along with IfcOpenShell. If not, see . import ifcopenshell +import ifcopenshell.api +import ifcopenshell.util.element import ifcopenshell.util.schema +from typing import Optional, Union class Usecase: - def __init__(self, file, product=None, reference=None, identification=None, name=None, classification=None, is_lightweight=True): - """Adds a new classification reference and assigns it to a product + def __init__( + self, + file: ifcopenshell.file, + products: list[ifcopenshell.entity_instance], + reference: Optional[ifcopenshell.entity_instance] = None, + identification: Optional[str] = None, + name: Optional[str] = None, + classification: Optional[ifcopenshell.entity_instance] = None, + is_lightweight=True, + ): + """Adds a new classification reference and assigns it to the list of products A classification reference is a single entry such as "Pr_12_23_34" that is part of an external classification system (such as Uniclass or @@ -33,7 +45,7 @@ class Usecase: resources such as profiles, documents, libraries, and so on. Classification references can be added in two ways. Option 1) specify a - custom arbitrary reference, where you have the manually specify the + custom arbitrary reference, where you have to manually specify the identification (e.g. "Pr_12_23_45") and name (e.g. "Door Products"). Option 2) add a reference from an IFC classification library. The latter is preferred if you are using a common classification system such as @@ -52,13 +64,13 @@ class Usecase: assigned to both the type and an occurrence, then the assignment at the occurrence will override the type classification. - :param product: The IFC object, property, or resource you want to + :param product: The list of IFC objects, properties, or resources you want to associate the classification reference to. - :type product: ifcopenshell.entity_instance.entity_instance + :type product: list[ifcopenshell.entity_instance.entity_instance] :param reference: The classification reference entity taken from an IFC classification library. If you supply this parameter, you will use option 2. - :type product: ifcopenshell.entity_instance.entity_instance, optional + :type reference: ifcopenshell.entity_instance.entity_instance, optional :param identification: If you choose option 1 and do not specify a reference, you may manually specify an identification code. The code is typically a short identifier and may have punctuation to separate @@ -70,7 +82,7 @@ class Usecase: :param classification: The IfcClassification entity in your IFC model (not the library, if you are doing option 2) that the reference is part of. - :type product: ifcopenshell.entity_instance.entity_instance + :type classification: ifcopenshell.entity_instance.entity_instance :param is_lightweight: If you are doing option 2, choose whether or not to only add that particular reference (lighweight) or also add all of its parent references in the classification hierarchy (not @@ -81,8 +93,12 @@ class Usecase: is generally unnecessary. Using lightweight classifications are recommended and is the default. :type is_lightweight: bool, optional + + :raises TypeError: If file is IFC2X3 and `products` has non-IfcRoot elements. + :return: The newly added IfcClassificationReference - :rtype: ifcopenshell.entity_instance.entity_instance + or `None` if `products` was empty list. + :rtype: Union[ifcopenshell.entity_instance.entity_instance, None] Example: @@ -93,7 +109,7 @@ class Usecase: classification = ifcopenshell.api.run("classification.add_classification", model, classification="MyCustomClassification") ifcopenshell.api.run("classification.add_reference", model, - product=wall_type, classification=classification, + products=[wall_type], classification=classification, identification="W_01", name="Interior Walls") # Option 2: adding a popular classification from a library @@ -104,12 +120,12 @@ class Usecase: reference = [r for r in library.by_type("IfcClassificationReference") if r.Identification == "XYZ"][0] ifcopenshell.api.run("classification.add_reference", model, - product=wall_type, classification=classification, + products=[wall_type], classification=classification, reference=reference) """ self.file = file self.settings = { - "product": product, + "products": products, "reference": reference, "identification": identification, "name": name, @@ -117,8 +133,27 @@ class Usecase: "is_lightweight": is_lightweight, } - def execute(self): - self.is_rooted = self.settings["product"].is_a("IfcRoot") + def execute(self) -> Union[ifcopenshell.entity_instance, None]: + if not self.settings["products"]: + return + + if self.settings["reference"]: + referenced = ifcopenshell.util.element.get_referenced_elements(self.settings["reference"]) + if set(self.settings["products"]).issubset(referenced): + # nothing to do, all elements already have this reference assigned + return self.settings["reference"] + + self.rooted_products: set[ifcopenshell.entity_instance] = set() + self.non_rooted_products: set[ifcopenshell.entity_instance] = set() + for product in self.settings["products"]: + if product.is_a("IfcRoot"): + self.rooted_products.add(product) + else: + self.non_rooted_products.add(product) + + if self.non_rooted_products and self.file.schema == "IFC2X3": + raise TypeError(f"Cannot add reference to non-IfcRoot element in IFC2X3: {self.non_rooted_products}.") + if self.settings["reference"]: return self.add_from_library() return self.add_from_identification() @@ -134,14 +169,10 @@ class Usecase: else: reference.Identification = self.settings["identification"] - relationship = self.get_existing_relationship(reference) - if relationship: - self.add_to_existing_relationship(relationship) - else: - self.add_new_relationship(reference) + self.update_relationships(reference) return reference - def add_from_library(self): + def add_from_library(self) -> ifcopenshell.entity_instance: if hasattr(self.settings["reference"], "ItemReference"): identification = self.settings["reference"].ItemReference # IFC2X3 else: @@ -155,8 +186,9 @@ class Usecase: old_referenced_source = self.settings["reference"].ReferencedSource self.settings["reference"].ReferencedSource = None else: + classification_name = self.settings["classification"].Name existing_classification = [ - c for c in self.file.by_type("IfcClassification") if c.Name == self.settings["classification"].Name + c for c in self.file.by_type("IfcClassification") if c.Name == classification_name ] reference = migrator.migrate(self.settings["reference"], self.file) @@ -174,15 +206,10 @@ class Usecase: for element in to_delete: self.file.remove(element) - relationship = self.get_existing_relationship(reference) - if relationship: - self.add_to_existing_relationship(relationship) - else: - self.add_new_relationship(reference) - + self.update_relationships(reference) return reference - def get_existing_reference(self, identification): + def get_existing_reference(self, identification: Optional[str] = None) -> Union[ifcopenshell.entity_instance, None]: for reference in self.file.by_type("IfcClassificationReference"): if self.file.schema == "IFC2X3": if reference.ItemReference == identification: @@ -191,39 +218,39 @@ class Usecase: if reference.Identification == identification: return reference - def add_new_relationship(self, reference): - if self.is_rooted: - self.file.create_entity( - "IfcRelAssociatesClassification", - GlobalId=ifcopenshell.guid.new(), - RelatedObjects=[self.settings["product"]], - RelatingClassification=reference, - ) - else: - self.file.create_entity( - "IfcExternalReferenceRelationship", - RelatingReference=reference, - RelatedResourceObjects=[self.settings["product"]], - ) - - def add_to_existing_relationship(self, rel): - if self.is_rooted: - related_objects = set(rel.RelatedObjects) - related_objects.add(self.settings["product"]) - rel.RelatedObjects = list(related_objects) - else: - related_objects = set(rel.RelatedResourceObjects) - related_objects.add(self.settings["product"]) - rel.RelatedResourceObjects = list(related_objects) - - def get_existing_relationship(self, reference): - if self.is_rooted: + def update_relationships(self, reference: ifcopenshell.entity_instance) -> None: + root_rel, non_root_rel = None, None + if self.rooted_products: if self.file.schema == "IFC2X3": for rel in self.file.by_type("IfcRelAssociatesClassification"): if rel.RelatingClassification == reference: - return rel - elif reference.ClassificationRefForObjects: - return reference.ClassificationRefForObjects[0] - elif self.file.schema != "IFC2X3": - if reference.ExternalReferenceForResources: - return reference.ExternalReferenceForResources[0] + root_rel = rel + break + else: + root_rel = next(iter(reference.ClassificationRefForObjects), None) + + if root_rel: + related_objects = set(root_rel.RelatedObjects) | self.rooted_products + root_rel.RelatedObjects = list(related_objects) + ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": root_rel}) + else: + self.file.create_entity( + "IfcRelAssociatesClassification", + OwnerHistory=ifcopenshell.api.run("owner.create_owner_history", self.file), + GlobalId=ifcopenshell.guid.new(), + RelatedObjects=list(self.rooted_products), + RelatingClassification=reference, + ) + + if self.non_rooted_products: + # NOTE: Only Ifc4+. Ifc2x3 is already handled by raising TypeError + non_root_rel = next(iter(reference.ExternalReferenceForResources), None) + if non_root_rel: + related_objects = set(non_root_rel.RelatedResourceObjects) | self.non_rooted_products + non_root_rel.RelatedResourceObjects = list(related_objects) + else: + self.file.create_entity( + "IfcExternalReferenceRelationship", + RelatingReference=reference, + RelatedResourceObjects=list(self.non_rooted_products), + ) diff --git a/src/ifcopenshell-python/ifcopenshell/api/classification/remove_reference.py b/src/ifcopenshell-python/ifcopenshell/api/classification/remove_reference.py index 48b55b3740..b91989a1ae 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/classification/remove_reference.py +++ b/src/ifcopenshell-python/ifcopenshell/api/classification/remove_reference.py @@ -44,7 +44,7 @@ class Usecase: classification = ifcopenshell.api.run("classification.add_classification", model, classification="MyCustomClassification") reference = ifcopenshell.api.run("classification.add_reference", model, - product=wall_type, classification=classification, + products=[wall_type], classification=classification, identification="W_01", name="Interior Walls") ifcopenshell.api.run("classification.remove_reference", model, reference=reference, product=wall_type) diff --git a/src/ifcopenshell-python/test/api/classification/test_add_reference.py b/src/ifcopenshell-python/test/api/classification/test_add_reference.py index 7cf5722b8f..ed52b05d35 100644 --- a/src/ifcopenshell-python/test/api/classification/test_add_reference.py +++ b/src/ifcopenshell-python/test/api/classification/test_add_reference.py @@ -16,6 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with IfcOpenShell. If not, see . +import pytest import test.bootstrap import ifcopenshell.api import ifcopenshell.util.classification @@ -23,85 +24,127 @@ import ifcopenshell.util.classification class TestAddReference(test.bootstrap.IFC4): def test_adding_a_reference(self): + is_ifc2x3 = self.file.schema == "IFC2X3" + ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") + element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") result = ifcopenshell.api.run("classification.add_classification", self.file, classification="Name") ifcopenshell.api.run( "classification.add_reference", self.file, - product=element, + products=[element, element2], identification="X", name="Foobar", classification=result, ) references = list(ifcopenshell.util.classification.get_references(element)) assert len(references) == 1 - assert references[0].Identification == "X" + assert getattr(references[0], "ItemReference" if is_ifc2x3 else "Identification") == "X" assert references[0].Name == "Foobar" assert references[0].ReferencedSource == self.file.by_type("IfcClassification")[0] - element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") - ifcopenshell.api.run( - "classification.add_reference", - self.file, - product=element2, - identification="X", - name="Foobar", - classification=result, + references2 = list(ifcopenshell.util.classification.get_references(element)) + assert len(references2) == 1 + assert getattr(references2[0], "ItemReference" if is_ifc2x3 else "Identification") == "X" + assert references2[0].Name == "Foobar" + assert references2[0] == references[0] + + rel = next( + rel + for rel in self.file.by_type("IfcRelAssociatesClassification") + if rel.RelatingClassification == references[0] ) - assert list(ifcopenshell.util.classification.get_references(element2))[0].Identification == "X" - assert list(ifcopenshell.util.classification.get_references(element2))[0].Name == "Foobar" - assert list(ifcopenshell.util.classification.get_references(element2))[0] == references[0] + assert len(rel.RelatedObjects) == 2 def test_adding_a_library_based_reference(self): + is_ifc2x3 = self.file.schema == "IFC2X3" + library = ifcopenshell.file() classification = library.createIfcClassification(Name="Name") reference = library.createIfcClassificationReference(Identification="1", ReferencedSource=classification) ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") + element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") result = ifcopenshell.api.run("classification.add_classification", self.file, classification=classification) ifcopenshell.api.run( "classification.add_reference", self.file, - product=element, + products=[element, element2], reference=reference, classification=result, ) references = list(ifcopenshell.util.classification.get_references(element)) assert len(references) == 1 - assert references[0].Identification == "1" + assert getattr(references[0], "ItemReference" if is_ifc2x3 else "Identification") == "1" assert references[0].ReferencedSource == self.file.by_type("IfcClassification")[0] - def test_adding_a_reference_to_a_resource(self): + references2 = list(ifcopenshell.util.classification.get_references(element2)) + assert len(references2) == 1 + assert getattr(references2[0], "ItemReference" if is_ifc2x3 else "Identification") == "1" + assert references2[0].ReferencedSource == self.file.by_type("IfcClassification")[0] + assert references[0] == references2[0] + + rel = next( + rel + for rel in self.file.by_type("IfcRelAssociatesClassification") + if rel.RelatingClassification == references[0] + ) + assert len(rel.RelatedObjects) == 2 + + def test_adding_a_reference_to_a_resource_and_to_a_root(self): ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") element = self.file.createIfcMaterial() + element2 = self.file.createIfcCostValue() + element3 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") result = ifcopenshell.api.run("classification.add_classification", self.file, classification="Name") - ifcopenshell.api.run( - "classification.add_reference", - self.file, - product=element, - identification="X", - name="Foobar", - classification=result, - ) + + if self.file.schema == "IFC2X3": + with pytest.raises(TypeError): + ifcopenshell.api.run( + "classification.add_reference", + self.file, + products=[element, element2, element3], + identification="X", + name="Foobar", + classification=result, + ) + return + else: + ifcopenshell.api.run( + "classification.add_reference", + self.file, + products=[element, element2, element3], + identification="X", + name="Foobar", + classification=result, + ) + references = list(ifcopenshell.util.classification.get_references(element)) assert len(references) == 1 assert references[0].Identification == "X" assert references[0].Name == "Foobar" assert references[0].ReferencedSource == self.file.by_type("IfcClassification")[0] - element2 = self.file.createIfcCostValue() - ifcopenshell.api.run( - "classification.add_reference", - self.file, - product=element2, - identification="X", - name="Foobar", - classification=result, - ) - assert list(ifcopenshell.util.classification.get_references(element2))[0].Identification == "X" - assert list(ifcopenshell.util.classification.get_references(element2))[0].Name == "Foobar" - assert list(ifcopenshell.util.classification.get_references(element2))[0] == references[0] + references2 = list(ifcopenshell.util.classification.get_references(element2)) + assert references2[0].Identification == "X" + assert references2[0].Name == "Foobar" + assert references2[0] == references[0] + + references3 = list(ifcopenshell.util.classification.get_references(element3)) + assert references3[0].Identification == "X" + assert references3[0].Name == "Foobar" + assert references3[0] == references[0] assert len(self.file.by_type("IfcExternalReferenceRelationship")[0].RelatedResourceObjects) == 2 + rel = next( + rel + for rel in self.file.by_type("IfcRelAssociatesClassification") + if rel.RelatingClassification == references[0] + ) + assert len(rel.RelatedObjects) == 1 + + +class TestAddReferenceIFC2X3(test.bootstrap.IFC2X3, TestAddReference): + pass diff --git a/src/ifcopenshell-python/test/api/classification/test_remove_classification.py b/src/ifcopenshell-python/test/api/classification/test_remove_classification.py index 3652d6e8c8..fb3537ddf2 100644 --- a/src/ifcopenshell-python/test/api/classification/test_remove_classification.py +++ b/src/ifcopenshell-python/test/api/classification/test_remove_classification.py @@ -34,7 +34,7 @@ class TestRemoveClassification(test.bootstrap.IFC4): ifcopenshell.api.run( "classification.add_reference", self.file, - product=element, + products=[element], identification="X", name="Foobar", classification=result, @@ -51,7 +51,7 @@ class TestRemoveClassification(test.bootstrap.IFC4): ifcopenshell.api.run( "classification.add_reference", self.file, - product=element, + products=[element], identification="X", name="Foobar", classification=result, diff --git a/src/ifcopenshell-python/test/api/classification/test_remove_reference.py b/src/ifcopenshell-python/test/api/classification/test_remove_reference.py index 597317f3bb..63ae287aa3 100644 --- a/src/ifcopenshell-python/test/api/classification/test_remove_reference.py +++ b/src/ifcopenshell-python/test/api/classification/test_remove_reference.py @@ -29,7 +29,7 @@ class TestRemoveReference(test.bootstrap.IFC4): reference = ifcopenshell.api.run( "classification.add_reference", self.file, - product=element, + products=[element], identification="X", name="Foobar", classification=result, @@ -45,7 +45,7 @@ class TestRemoveReference(test.bootstrap.IFC4): reference = ifcopenshell.api.run( "classification.add_reference", self.file, - product=element, + products=[element], identification="X", name="Foobar", classification=result, @@ -62,7 +62,7 @@ class TestRemoveReference(test.bootstrap.IFC4): reference = ifcopenshell.api.run( "classification.add_reference", self.file, - product=element, + products=[element], identification="X", name="Foobar", classification=result, @@ -70,7 +70,7 @@ class TestRemoveReference(test.bootstrap.IFC4): reference2 = ifcopenshell.api.run( "classification.add_reference", self.file, - product=element2, + products=[element2], identification="X", name="Foobar", classification=result, diff --git a/src/ifcopenshell-python/test/api/test_api.py b/src/ifcopenshell-python/test/api/test_api.py index 779d1238f2..7910cf9739 100644 --- a/src/ifcopenshell-python/test/api/test_api.py +++ b/src/ifcopenshell-python/test/api/test_api.py @@ -18,6 +18,7 @@ import test.bootstrap import ifcopenshell.api +import ifcopenshell.util.classification import ifcopenshell.util.element import ifcopenshell.util.system from datetime import datetime @@ -186,3 +187,35 @@ class TestTemporarySupportForDeprecatedAPIArguments(test.bootstrap.IFC4): assert len(self.file.by_type("IfcRelAssociatesMaterial")) == 0 assert len(self.file.by_type("IfcWall")) == 1 assert len(self.file.by_type("IfcMaterial")) == 1 + + @deprecation_check + def test_adding_a_reference(self): + ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") + element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") + result = ifcopenshell.api.run("classification.add_classification", self.file, classification="Name") + ifcopenshell.api.run( + "classification.add_reference", + self.file, + product=element, + identification="X", + name="Foobar", + classification=result, + ) + references = list(ifcopenshell.util.classification.get_references(element)) + assert len(references) == 1 + assert references[0].Identification == "X" + assert references[0].Name == "Foobar" + assert references[0].ReferencedSource == self.file.by_type("IfcClassification")[0] + + element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") + ifcopenshell.api.run( + "classification.add_reference", + self.file, + product=element2, + identification="X", + name="Foobar", + classification=result, + ) + assert list(ifcopenshell.util.classification.get_references(element2))[0].Identification == "X" + assert list(ifcopenshell.util.classification.get_references(element2))[0].Name == "Foobar" + assert list(ifcopenshell.util.classification.get_references(element2))[0] == references[0] diff --git a/src/ifcopenshell-python/test/util/test_classification.py b/src/ifcopenshell-python/test/util/test_classification.py index d394f8056b..7fe054e1e3 100644 --- a/src/ifcopenshell-python/test/util/test_classification.py +++ b/src/ifcopenshell-python/test/util/test_classification.py @@ -34,14 +34,14 @@ class TestGetReferences(test.bootstrap.IFC4): ifcopenshell.api.run( "classification.add_reference", self.file, - product=element, + products=[element], reference=reference1, classification=classification, ) ifcopenshell.api.run( "classification.add_reference", self.file, - product=element, + products=[element], reference=reference2, classification=classification, ) @@ -54,7 +54,7 @@ class TestGetReferences(test.bootstrap.IFC4): ifcopenshell.api.run( "classification.add_reference", self.file, - product=element, + products=[element], identification="X", name="Foobar", classification=result, @@ -74,14 +74,14 @@ class TestGetReferences(test.bootstrap.IFC4): ifcopenshell.api.run( "classification.add_reference", self.file, - product=element, + products=[element], reference=reference1, classification=classification, ) ifcopenshell.api.run( "classification.add_reference", self.file, - product=element_type, + products=[element_type], reference=reference2, classification=classification, ) @@ -103,14 +103,14 @@ class TestGetReferences(test.bootstrap.IFC4): ifcopenshell.api.run( "classification.add_reference", self.file, - product=element, + products=[element], reference=reference1, classification=classification, ) ifcopenshell.api.run( "classification.add_reference", self.file, - product=element_type, + products=[element_type], reference=reference2, classification=classification, ) diff --git a/src/ifcopenshell-python/test/util/test_selector.py b/src/ifcopenshell-python/test/util/test_selector.py index d8ba4bb174..571511d39f 100644 --- a/src/ifcopenshell-python/test/util/test_selector.py +++ b/src/ifcopenshell-python/test/util/test_selector.py @@ -225,7 +225,7 @@ class TestFilterElements(test.bootstrap.IFC4): ifcopenshell.api.run( "classification.add_reference", self.file, - product=element, + products=[element], identification="X", name="Foobar", classification=result, diff --git a/src/ifctester/test/test_facet.py b/src/ifctester/test/test_facet.py index bd89a00946..ddee91ab36 100644 --- a/src/ifctester/test/test_facet.py +++ b/src/ifctester/test/test_facet.py @@ -706,24 +706,24 @@ class TestClassification: 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, product=element1, reference=ref1, classification=system_a + "classification.add_reference", ifc, products=[element1], reference=ref1, classification=system_a ) element11 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcColumn") ifcopenshell.api.run( - "classification.add_reference", ifc, product=element11, reference=ref11, classification=system_a + "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", ifc, - product=element22, + products=[element22], reference=ref22, classification=system_a, is_lightweight=False, ) material = ifc.createIfcMaterial(Name="Material") ifcopenshell.api.run( - "classification.add_reference", ifc, product=material, reference=ref1, classification=system_a + "classification.add_reference", ifc, products=[material], reference=ref1, classification=system_a ) facet = Classification(system="Foobar") @@ -810,15 +810,15 @@ class TestClassification: 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, product=wall, reference=ref11, classification=system_a + "classification.add_reference", ifc, products=[wall], reference=ref11, classification=system_a ) ifcopenshell.api.run( - "classification.add_reference", ifc, product=wall_type, reference=ref22, classification=system_a + "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, product=wall_type, reference=refx, classification=system_b + "classification.add_reference", ifc, products=[wall_type], reference=refx, classification=system_b ) facet = Classification(system="Foobar", value="11")