Implement IDS partOf facet

This commit is contained in:
Dion Moult
2022-05-12 14:33:44 +10:00
parent 4da5a38237
commit fdaae048c2
2 changed files with 81 additions and 52 deletions
+17 -52
View File
@@ -731,13 +731,9 @@ class partOf(facet):
parameters = ["entity"]
message = "relation as part of %(entity)s"
# TODO temp default
entity = "IfcElementAssembly"
@staticmethod
# TODO should not assume IfcElementAssembly
# def create(entity=None):
def create(entity="IfcElementAssembly"):
def create(entity="IfcSystem"):
"""Create a partOf facet that can be added to applicability or requirements of IDS specification.
:param entity: Entity that should contain this object. Could be alphanumeric or restriction object, defaults to None
@@ -756,13 +752,9 @@ class partOf(facet):
:return: Xmlschema compliant dictionary.
:rtype: dict
"""
fac_dict = {
"@entity": parameter_asdict(self.entity),
# "instructions": "SAMPLE_INSTRUCTIONS",
}
return fac_dict
return {"@entity": parameter_asdict(self.entity)}
def __call__(self, inst, logger):
def __call__(self, inst, logger=None):
"""Validate an ifc instance against that partOf facet.
:param inst: IFC entity element
@@ -772,48 +764,21 @@ class partOf(facet):
:return: result of the validation as bool and message
:rtype: facet_evaluation(bool, str)
"""
# TODO handle partOf facet
# instance_classiciations = inst.HasAssociations
# if ifcopenshell.util.element.get_type(inst):
# type_classifications = ifcopenshell.util.element.get_type(inst).HasAssociations
# else:
# type_classifications = ()
# if self.location == "instance" and instance_classiciations:
# associations = instance_classiciations
# elif self.location == "type" and type_classifications:
# associations = type_classifications
# elif self.location == "any" and (instance_classiciations or type_classifications):
# associations = instance_classiciations + type_classifications
# else:
# associations = ()
refs = []
# for association in associations:
# if association.is_a("IfcRelAssociatesClassification"):
# cref = association.RelatingClassification
# if hasattr(cref, "ItemReference"): # IFC2x3
# refs.append((cref.ReferencedSource.Name, cref.ItemReference))
# elif hasattr(cref, "Identification"): # IFC4
# refs.append((cref.ReferencedSource.Name, cref.Identification))
# self.location_msg = location[self.location]
if refs:
pass
# return facet_evaluation(
# (self.system, self.value) in refs,
# self.message
# % {
# "system": refs[0][0],
# "value": "'" + refs[0][1] + "'",
# "location": self.location_msg,
# }, # what if not first item of refs?
# )
if self.entity == "IfcElementAssembly":
is_pass = False
aggregate = ifcopenshell.util.element.get_aggregate(inst)
while aggregate is not None:
if aggregate.is_a() == "IfcElementAssembly":
is_pass = True
break
aggregate = ifcopenshell.util.element.get_aggregate(aggregate)
else:
return facet_evaluation(False, "is not a part of %s" % self.node["@entity"])
is_pass = False
for rel in getattr(inst, "HasAssignments", []) or []:
if rel.is_a("IfcRelAssignsToGroup") and rel.RelatingGroup.is_a(self.entity):
is_pass = True
return facet_evaluation(is_pass, "is not a part of")
class property(facet):
+64
View File
@@ -961,6 +961,70 @@ class TestIdsAuthoring(unittest.TestCase):
assert bool(facet(element)) is True
assert bool(facet(element_type)) is False
def test_creating_a_partof_facet(self):
facet = ids.partOf.create()
assert facet.asdict() == {"@entity": {"simpleValue": "IfcSystem"}}
facet = ids.partOf.create(entity="IfcGroup")
assert facet.asdict() == {"@entity": {"simpleValue": "IfcGroup"}}
def test_filtering_using_a_partof_facet(self):
ifc = ifcopenshell.file()
# An IfcElementAssembly entity only passes those who are part of an assembly
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcElementAssembly")
subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
ifcopenshell.api.run("aggregate.assign_object", ifc, product=subelement, relating_object=element)
facet = ids.partOf.create(entity="IfcElementAssembly")
assert bool(facet(element)) is False
assert bool(facet(subelement)) is True
# An IfcElementAssembly strictly checks that the whole is an IfcElementAssembly class
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcSlab")
subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcBeam")
ifcopenshell.api.run("aggregate.assign_object", ifc, product=subelement, relating_object=element)
facet = ids.partOf.create(entity="IfcElementAssembly")
assert bool(facet(subelement)) is False
# A nested subelement still passes so long as one of its parents is an IfcElementAssembly
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcElementAssembly")
subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcSlab")
subsubelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcBeam")
ifcopenshell.api.run("aggregate.assign_object", ifc, product=subelement, relating_object=element)
ifcopenshell.api.run("aggregate.assign_object", ifc, product=subsubelement, relating_object=subelement)
facet = ids.partOf.create(entity="IfcElementAssembly")
assert bool(facet(subsubelement)) is True
# An IfcGroup only checks that a group is assigned without any other logic
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcElementAssembly")
group = ifcopenshell.api.run("group.add_group", ifc)
facet = ids.partOf.create(entity="IfcGroup")
assert bool(facet(element)) is False
ifcopenshell.api.run("group.assign_group", ifc, product=element, group=group)
assert bool(facet(element)) is True
# An IfcGroup can be passed by subtypes
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcElementAssembly")
group = ifc.createIfcInventory()
facet = ids.partOf.create(entity="IfcGroup")
ifcopenshell.api.run("group.assign_group", ifc, product=element, group=group)
assert bool(facet(element)) is True
# An IfcSystem only checks that a system is assigned without any other logic
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcElementAssembly")
system = ifcopenshell.api.run("system.add_system", ifc)
facet = ids.partOf.create(entity="IfcSystem")
assert bool(facet(element)) is False
ifcopenshell.api.run("system.assign_system", ifc, product=element, system=system)
assert bool(facet(element)) is True
# An IfcSystem allows subtypes
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcElementAssembly")
system = ifcopenshell.api.run("system.add_system", ifc, ifc_class="IfcDistributionSystem")
ifcopenshell.api.run("system.assign_system", ifc, product=element, system=system)
facet = ids.partOf.create(entity="IfcSystem")
assert bool(facet(element)) is True
""" Creating IDS with restrictions """
def test_create_restrictions_enumeration(self):