mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Implement IDS partOf facet
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user