mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
classification.add_reference - support batching #4474
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
Reference in New Issue
Block a user