classification.add_reference - support batching #4474

This commit is contained in:
Andrej730
2024-04-15 12:06:39 +05:00
parent 7d6fd03eb4
commit d6e69bd6e9
11 changed files with 234 additions and 125 deletions
@@ -88,7 +88,7 @@ class AddManualClassificationReference(bpy.types.Operator, tool.Ifc.Operator):
reference = ifcopenshell.api.run( reference = ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
tool.Ifc.get(), tool.Ifc.get(),
product=product, products=[product],
classification=classification, classification=classification,
identification="X", identification="X",
name="Unnamed", name="Unnamed",
@@ -358,15 +358,18 @@ class AddClassificationReference(bpy.types.Operator, tool.Ifc.Operator):
classification = element classification = element
break break
for obj in objects: ifc_file = tool.Ifc.get()
ifc_definition_id = tool.Blender.get_obj_ifc_definition_id(obj, self.obj_type, context) products = [
if not ifc_definition_id: ifc_file.by_id(ifc_definition_id)
continue 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( ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
tool.Ifc.get(), tool.Ifc.get(),
reference=IfcStore.classification_file.by_id(self.reference), reference=IfcStore.classification_file.by_id(self.reference),
product=tool.Ifc.get().by_id(ifc_definition_id), products=products,
classification=classification, classification=classification,
) )
@@ -414,7 +417,7 @@ class AddClassificationReferenceFromBSDD(bpy.types.Operator, tool.Ifc.Operator):
reference = ifcopenshell.api.run( reference = ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
tool.Ifc.get(), tool.Ifc.get(),
product=element, products=[element],
classification=classification, classification=classification,
identification=bsdd_classification.reference_code, identification=bsdd_classification.reference_code,
name=bsdd_classification.name, name=bsdd_classification.name,
@@ -87,6 +87,9 @@ ARGUMENTS_DEPRECATION = {
"material.unassign_material": partial( "material.unassign_material": partial(
batching_argument_deprecation, prev_argument="product", new_argument="products" batching_argument_deprecation, prev_argument="product", new_argument="products"
), ),
"classification.add_reference": partial(
batching_argument_deprecation, prev_argument="product", new_argument="products"
),
} }
@@ -17,12 +17,24 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>. # along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.element
import ifcopenshell.util.schema import ifcopenshell.util.schema
from typing import Optional, Union
class Usecase: class Usecase:
def __init__(self, file, product=None, reference=None, identification=None, name=None, classification=None, is_lightweight=True): def __init__(
"""Adds a new classification reference and assigns it to a product 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 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 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. resources such as profiles, documents, libraries, and so on.
Classification references can be added in two ways. Option 1) specify a 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"). 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 Option 2) add a reference from an IFC classification library. The latter
is preferred if you are using a common classification system such as 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 assigned to both the type and an occurrence, then the assignment at the
occurrence will override the type classification. 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. 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 :param reference: The classification reference entity taken from an
IFC classification library. If you supply this parameter, you will IFC classification library. If you supply this parameter, you will
use option 2. 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 :param identification: If you choose option 1 and do not specify a
reference, you may manually specify an identification code. The code reference, you may manually specify an identification code. The code
is typically a short identifier and may have punctuation to separate 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 :param classification: The IfcClassification entity in your IFC model
(not the library, if you are doing option 2) that the reference is (not the library, if you are doing option 2) that the reference is
part of. 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 :param is_lightweight: If you are doing option 2, choose whether or not
to only add that particular reference (lighweight) or also add all to only add that particular reference (lighweight) or also add all
of its parent references in the classification hierarchy (not of its parent references in the classification hierarchy (not
@@ -81,8 +93,12 @@ class Usecase:
is generally unnecessary. Using lightweight classifications are is generally unnecessary. Using lightweight classifications are
recommended and is the default. recommended and is the default.
:type is_lightweight: bool, optional :type is_lightweight: bool, optional
:raises TypeError: If file is IFC2X3 and `products` has non-IfcRoot elements.
:return: The newly added IfcClassificationReference :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: Example:
@@ -93,7 +109,7 @@ class Usecase:
classification = ifcopenshell.api.run("classification.add_classification", classification = ifcopenshell.api.run("classification.add_classification",
model, classification="MyCustomClassification") model, classification="MyCustomClassification")
ifcopenshell.api.run("classification.add_reference", model, ifcopenshell.api.run("classification.add_reference", model,
product=wall_type, classification=classification, products=[wall_type], classification=classification,
identification="W_01", name="Interior Walls") identification="W_01", name="Interior Walls")
# Option 2: adding a popular classification from a library # Option 2: adding a popular classification from a library
@@ -104,12 +120,12 @@ class Usecase:
reference = [r for r in library.by_type("IfcClassificationReference") reference = [r for r in library.by_type("IfcClassificationReference")
if r.Identification == "XYZ"][0] if r.Identification == "XYZ"][0]
ifcopenshell.api.run("classification.add_reference", model, ifcopenshell.api.run("classification.add_reference", model,
product=wall_type, classification=classification, products=[wall_type], classification=classification,
reference=reference) reference=reference)
""" """
self.file = file self.file = file
self.settings = { self.settings = {
"product": product, "products": products,
"reference": reference, "reference": reference,
"identification": identification, "identification": identification,
"name": name, "name": name,
@@ -117,8 +133,27 @@ class Usecase:
"is_lightweight": is_lightweight, "is_lightweight": is_lightweight,
} }
def execute(self): def execute(self) -> Union[ifcopenshell.entity_instance, None]:
self.is_rooted = self.settings["product"].is_a("IfcRoot") 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"]: if self.settings["reference"]:
return self.add_from_library() return self.add_from_library()
return self.add_from_identification() return self.add_from_identification()
@@ -134,14 +169,10 @@ class Usecase:
else: else:
reference.Identification = self.settings["identification"] reference.Identification = self.settings["identification"]
relationship = self.get_existing_relationship(reference) self.update_relationships(reference)
if relationship:
self.add_to_existing_relationship(relationship)
else:
self.add_new_relationship(reference)
return reference return reference
def add_from_library(self): def add_from_library(self) -> ifcopenshell.entity_instance:
if hasattr(self.settings["reference"], "ItemReference"): if hasattr(self.settings["reference"], "ItemReference"):
identification = self.settings["reference"].ItemReference # IFC2X3 identification = self.settings["reference"].ItemReference # IFC2X3
else: else:
@@ -155,8 +186,9 @@ class Usecase:
old_referenced_source = self.settings["reference"].ReferencedSource old_referenced_source = self.settings["reference"].ReferencedSource
self.settings["reference"].ReferencedSource = None self.settings["reference"].ReferencedSource = None
else: else:
classification_name = self.settings["classification"].Name
existing_classification = [ 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) reference = migrator.migrate(self.settings["reference"], self.file)
@@ -174,15 +206,10 @@ class Usecase:
for element in to_delete: for element in to_delete:
self.file.remove(element) self.file.remove(element)
relationship = self.get_existing_relationship(reference) self.update_relationships(reference)
if relationship:
self.add_to_existing_relationship(relationship)
else:
self.add_new_relationship(reference)
return 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"): for reference in self.file.by_type("IfcClassificationReference"):
if self.file.schema == "IFC2X3": if self.file.schema == "IFC2X3":
if reference.ItemReference == identification: if reference.ItemReference == identification:
@@ -191,39 +218,39 @@ class Usecase:
if reference.Identification == identification: if reference.Identification == identification:
return reference return reference
def add_new_relationship(self, reference): def update_relationships(self, reference: ifcopenshell.entity_instance) -> None:
if self.is_rooted: root_rel, non_root_rel = None, None
self.file.create_entity( if self.rooted_products:
"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:
if self.file.schema == "IFC2X3": if self.file.schema == "IFC2X3":
for rel in self.file.by_type("IfcRelAssociatesClassification"): for rel in self.file.by_type("IfcRelAssociatesClassification"):
if rel.RelatingClassification == reference: if rel.RelatingClassification == reference:
return rel root_rel = rel
elif reference.ClassificationRefForObjects: break
return reference.ClassificationRefForObjects[0] else:
elif self.file.schema != "IFC2X3": root_rel = next(iter(reference.ClassificationRefForObjects), None)
if reference.ExternalReferenceForResources:
return reference.ExternalReferenceForResources[0] 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),
)
@@ -44,7 +44,7 @@ class Usecase:
classification = ifcopenshell.api.run("classification.add_classification", classification = ifcopenshell.api.run("classification.add_classification",
model, classification="MyCustomClassification") model, classification="MyCustomClassification")
reference = ifcopenshell.api.run("classification.add_reference", model, reference = ifcopenshell.api.run("classification.add_reference", model,
product=wall_type, classification=classification, products=[wall_type], classification=classification,
identification="W_01", name="Interior Walls") identification="W_01", name="Interior Walls")
ifcopenshell.api.run("classification.remove_reference", model, ifcopenshell.api.run("classification.remove_reference", model,
reference=reference, product=wall_type) reference=reference, product=wall_type)
@@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>. # along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import pytest
import test.bootstrap import test.bootstrap
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.classification import ifcopenshell.util.classification
@@ -23,85 +24,127 @@ import ifcopenshell.util.classification
class TestAddReference(test.bootstrap.IFC4): class TestAddReference(test.bootstrap.IFC4):
def test_adding_a_reference(self): def test_adding_a_reference(self):
is_ifc2x3 = self.file.schema == "IFC2X3"
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") 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") result = ifcopenshell.api.run("classification.add_classification", self.file, classification="Name")
ifcopenshell.api.run( ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
self.file, self.file,
product=element, products=[element, element2],
identification="X", identification="X",
name="Foobar", name="Foobar",
classification=result, classification=result,
) )
references = list(ifcopenshell.util.classification.get_references(element)) references = list(ifcopenshell.util.classification.get_references(element))
assert len(references) == 1 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].Name == "Foobar"
assert references[0].ReferencedSource == self.file.by_type("IfcClassification")[0] assert references[0].ReferencedSource == self.file.by_type("IfcClassification")[0]
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") references2 = list(ifcopenshell.util.classification.get_references(element))
ifcopenshell.api.run( assert len(references2) == 1
"classification.add_reference", assert getattr(references2[0], "ItemReference" if is_ifc2x3 else "Identification") == "X"
self.file, assert references2[0].Name == "Foobar"
product=element2, assert references2[0] == references[0]
identification="X",
name="Foobar", rel = next(
classification=result, 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 len(rel.RelatedObjects) == 2
assert list(ifcopenshell.util.classification.get_references(element2))[0].Name == "Foobar"
assert list(ifcopenshell.util.classification.get_references(element2))[0] == references[0]
def test_adding_a_library_based_reference(self): def test_adding_a_library_based_reference(self):
is_ifc2x3 = self.file.schema == "IFC2X3"
library = ifcopenshell.file() library = ifcopenshell.file()
classification = library.createIfcClassification(Name="Name") classification = library.createIfcClassification(Name="Name")
reference = library.createIfcClassificationReference(Identification="1", ReferencedSource=classification) reference = library.createIfcClassificationReference(Identification="1", ReferencedSource=classification)
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") 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) result = ifcopenshell.api.run("classification.add_classification", self.file, classification=classification)
ifcopenshell.api.run( ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
self.file, self.file,
product=element, products=[element, element2],
reference=reference, reference=reference,
classification=result, classification=result,
) )
references = list(ifcopenshell.util.classification.get_references(element)) references = list(ifcopenshell.util.classification.get_references(element))
assert len(references) == 1 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] 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") ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
element = self.file.createIfcMaterial() 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") result = ifcopenshell.api.run("classification.add_classification", self.file, classification="Name")
ifcopenshell.api.run(
"classification.add_reference", if self.file.schema == "IFC2X3":
self.file, with pytest.raises(TypeError):
product=element, ifcopenshell.api.run(
identification="X", "classification.add_reference",
name="Foobar", self.file,
classification=result, 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)) references = list(ifcopenshell.util.classification.get_references(element))
assert len(references) == 1 assert len(references) == 1
assert references[0].Identification == "X" assert references[0].Identification == "X"
assert references[0].Name == "Foobar" assert references[0].Name == "Foobar"
assert references[0].ReferencedSource == self.file.by_type("IfcClassification")[0] assert references[0].ReferencedSource == self.file.by_type("IfcClassification")[0]
element2 = self.file.createIfcCostValue() references2 = list(ifcopenshell.util.classification.get_references(element2))
ifcopenshell.api.run( assert references2[0].Identification == "X"
"classification.add_reference", assert references2[0].Name == "Foobar"
self.file, assert references2[0] == references[0]
product=element2,
identification="X", references3 = list(ifcopenshell.util.classification.get_references(element3))
name="Foobar", assert references3[0].Identification == "X"
classification=result, assert references3[0].Name == "Foobar"
) assert references3[0] == 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(self.file.by_type("IfcExternalReferenceRelationship")[0].RelatedResourceObjects) == 2 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
@@ -34,7 +34,7 @@ class TestRemoveClassification(test.bootstrap.IFC4):
ifcopenshell.api.run( ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
self.file, self.file,
product=element, products=[element],
identification="X", identification="X",
name="Foobar", name="Foobar",
classification=result, classification=result,
@@ -51,7 +51,7 @@ class TestRemoveClassification(test.bootstrap.IFC4):
ifcopenshell.api.run( ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
self.file, self.file,
product=element, products=[element],
identification="X", identification="X",
name="Foobar", name="Foobar",
classification=result, classification=result,
@@ -29,7 +29,7 @@ class TestRemoveReference(test.bootstrap.IFC4):
reference = ifcopenshell.api.run( reference = ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
self.file, self.file,
product=element, products=[element],
identification="X", identification="X",
name="Foobar", name="Foobar",
classification=result, classification=result,
@@ -45,7 +45,7 @@ class TestRemoveReference(test.bootstrap.IFC4):
reference = ifcopenshell.api.run( reference = ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
self.file, self.file,
product=element, products=[element],
identification="X", identification="X",
name="Foobar", name="Foobar",
classification=result, classification=result,
@@ -62,7 +62,7 @@ class TestRemoveReference(test.bootstrap.IFC4):
reference = ifcopenshell.api.run( reference = ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
self.file, self.file,
product=element, products=[element],
identification="X", identification="X",
name="Foobar", name="Foobar",
classification=result, classification=result,
@@ -70,7 +70,7 @@ class TestRemoveReference(test.bootstrap.IFC4):
reference2 = ifcopenshell.api.run( reference2 = ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
self.file, self.file,
product=element2, products=[element2],
identification="X", identification="X",
name="Foobar", name="Foobar",
classification=result, classification=result,
@@ -18,6 +18,7 @@
import test.bootstrap import test.bootstrap
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.classification
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.system import ifcopenshell.util.system
from datetime import datetime 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("IfcRelAssociatesMaterial")) == 0
assert len(self.file.by_type("IfcWall")) == 1 assert len(self.file.by_type("IfcWall")) == 1
assert len(self.file.by_type("IfcMaterial")) == 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]
@@ -34,14 +34,14 @@ class TestGetReferences(test.bootstrap.IFC4):
ifcopenshell.api.run( ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
self.file, self.file,
product=element, products=[element],
reference=reference1, reference=reference1,
classification=classification, classification=classification,
) )
ifcopenshell.api.run( ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
self.file, self.file,
product=element, products=[element],
reference=reference2, reference=reference2,
classification=classification, classification=classification,
) )
@@ -54,7 +54,7 @@ class TestGetReferences(test.bootstrap.IFC4):
ifcopenshell.api.run( ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
self.file, self.file,
product=element, products=[element],
identification="X", identification="X",
name="Foobar", name="Foobar",
classification=result, classification=result,
@@ -74,14 +74,14 @@ class TestGetReferences(test.bootstrap.IFC4):
ifcopenshell.api.run( ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
self.file, self.file,
product=element, products=[element],
reference=reference1, reference=reference1,
classification=classification, classification=classification,
) )
ifcopenshell.api.run( ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
self.file, self.file,
product=element_type, products=[element_type],
reference=reference2, reference=reference2,
classification=classification, classification=classification,
) )
@@ -103,14 +103,14 @@ class TestGetReferences(test.bootstrap.IFC4):
ifcopenshell.api.run( ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
self.file, self.file,
product=element, products=[element],
reference=reference1, reference=reference1,
classification=classification, classification=classification,
) )
ifcopenshell.api.run( ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
self.file, self.file,
product=element_type, products=[element_type],
reference=reference2, reference=reference2,
classification=classification, classification=classification,
) )
@@ -225,7 +225,7 @@ class TestFilterElements(test.bootstrap.IFC4):
ifcopenshell.api.run( ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
self.file, self.file,
product=element, products=[element],
identification="X", identification="X",
name="Foobar", name="Foobar",
classification=result, classification=result,
+7 -7
View File
@@ -706,24 +706,24 @@ class TestClassification:
element0 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") element0 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
element1 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcSlab") element1 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcSlab")
ifcopenshell.api.run( 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") element11 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcColumn")
ifcopenshell.api.run( 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") element22 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcBeam")
ifcopenshell.api.run( ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
ifc, ifc,
product=element22, products=[element22],
reference=ref22, reference=ref22,
classification=system_a, classification=system_a,
is_lightweight=False, is_lightweight=False,
) )
material = ifc.createIfcMaterial(Name="Material") material = ifc.createIfcMaterial(Name="Material")
ifcopenshell.api.run( 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") facet = Classification(system="Foobar")
@@ -810,15 +810,15 @@ class TestClassification:
wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType") 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("type.assign_type", ifc, related_objects=[wall], relating_type=wall_type)
ifcopenshell.api.run( 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( 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) system_b = ifcopenshell.api.run("classification.add_classification", ifc, classification=system_b)
ifcopenshell.api.run( 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") facet = Classification(system="Foobar", value="11")