mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-16 04:12:13 +00:00
Implement IDS partOf facet
This commit is contained in:
@@ -731,13 +731,9 @@ class partOf(facet):
|
|||||||
|
|
||||||
parameters = ["entity"]
|
parameters = ["entity"]
|
||||||
message = "relation as part of %(entity)s"
|
message = "relation as part of %(entity)s"
|
||||||
# TODO temp default
|
|
||||||
entity = "IfcElementAssembly"
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
# TODO should not assume IfcElementAssembly
|
def create(entity="IfcSystem"):
|
||||||
# def create(entity=None):
|
|
||||||
def create(entity="IfcElementAssembly"):
|
|
||||||
"""Create a partOf facet that can be added to applicability or requirements of IDS specification.
|
"""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
|
: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.
|
:return: Xmlschema compliant dictionary.
|
||||||
:rtype: dict
|
:rtype: dict
|
||||||
"""
|
"""
|
||||||
fac_dict = {
|
return {"@entity": parameter_asdict(self.entity)}
|
||||||
"@entity": parameter_asdict(self.entity),
|
|
||||||
# "instructions": "SAMPLE_INSTRUCTIONS",
|
|
||||||
}
|
|
||||||
return fac_dict
|
|
||||||
|
|
||||||
def __call__(self, inst, logger):
|
def __call__(self, inst, logger=None):
|
||||||
"""Validate an ifc instance against that partOf facet.
|
"""Validate an ifc instance against that partOf facet.
|
||||||
|
|
||||||
:param inst: IFC entity element
|
:param inst: IFC entity element
|
||||||
@@ -772,48 +764,21 @@ class partOf(facet):
|
|||||||
:return: result of the validation as bool and message
|
:return: result of the validation as bool and message
|
||||||
:rtype: facet_evaluation(bool, str)
|
:rtype: facet_evaluation(bool, str)
|
||||||
"""
|
"""
|
||||||
|
if self.entity == "IfcElementAssembly":
|
||||||
# TODO handle partOf facet
|
is_pass = False
|
||||||
|
aggregate = ifcopenshell.util.element.get_aggregate(inst)
|
||||||
# instance_classiciations = inst.HasAssociations
|
while aggregate is not None:
|
||||||
# if ifcopenshell.util.element.get_type(inst):
|
if aggregate.is_a() == "IfcElementAssembly":
|
||||||
# type_classifications = ifcopenshell.util.element.get_type(inst).HasAssociations
|
is_pass = True
|
||||||
# else:
|
break
|
||||||
# type_classifications = ()
|
aggregate = ifcopenshell.util.element.get_aggregate(aggregate)
|
||||||
|
|
||||||
# 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?
|
|
||||||
# )
|
|
||||||
else:
|
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):
|
class property(facet):
|
||||||
|
|||||||
@@ -961,6 +961,70 @@ class TestIdsAuthoring(unittest.TestCase):
|
|||||||
assert bool(facet(element)) is True
|
assert bool(facet(element)) is True
|
||||||
assert bool(facet(element_type)) is False
|
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 """
|
""" Creating IDS with restrictions """
|
||||||
|
|
||||||
def test_create_restrictions_enumeration(self):
|
def test_create_restrictions_enumeration(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user