mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-17 10:59:17 +00:00
IfcTester now supports new entityType data in partof facet
This commit is contained in:
@@ -302,8 +302,8 @@ class Classification(Facet):
|
||||
|
||||
|
||||
class PartOf(Facet):
|
||||
def __init__(self, entity=None, relation="IfcRelAggregates", minOccurs=None, maxOccurs=None, instructions=None):
|
||||
self.parameters = ["entity", "@relation", "@minOccurs", "@maxOccurs", "@instructions"]
|
||||
def __init__(self, entity=None, predefinedType=None, relation="IfcRelAggregates", minOccurs=None, maxOccurs=None, instructions=None):
|
||||
self.parameters = ["entity", "predefinedType", "@relation", "@minOccurs", "@maxOccurs", "@instructions"]
|
||||
self.applicability_templates = [
|
||||
"An element with an {relation} relationship with an {entity}",
|
||||
"An element with an {relation} relationship",
|
||||
@@ -312,7 +312,26 @@ class PartOf(Facet):
|
||||
"An element must have an {relation} relationship with an {entity}",
|
||||
"An element must have an {relation} relationship",
|
||||
]
|
||||
super().__init__(entity, relation, minOccurs, maxOccurs, instructions)
|
||||
super().__init__(entity, predefinedType, relation, minOccurs, maxOccurs, instructions)
|
||||
|
||||
def asdict(self):
|
||||
results = super().asdict()
|
||||
entity = {}
|
||||
if "entity" in results:
|
||||
entity["name"] = results["entity"]
|
||||
del results["entity"]
|
||||
if "predefinedType" in results:
|
||||
entity["predefinedType"] = results["predefinedType"]
|
||||
del results["predefinedType"]
|
||||
if entity:
|
||||
results["entity"] = entity
|
||||
return results
|
||||
|
||||
def parse(self, xml):
|
||||
if "entity" in xml:
|
||||
super().parse(xml["entity"])
|
||||
del xml["entity"]
|
||||
super().parse(xml)
|
||||
|
||||
def __call__(self, inst, logger=None):
|
||||
if self.minOccurs == 0 and self.maxOccurs != 0:
|
||||
@@ -330,7 +349,11 @@ class PartOf(Facet):
|
||||
while aggregate is not None:
|
||||
ancestors.append(aggregate.is_a())
|
||||
if aggregate.is_a().upper() == self.entity:
|
||||
is_pass = True
|
||||
if self.predefinedType:
|
||||
if ifcopenshell.util.element.get_predefined_type(aggregate) == self.predefinedType:
|
||||
is_pass = True
|
||||
else:
|
||||
is_pass = True
|
||||
break
|
||||
aggregate = ifcopenshell.util.element.get_aggregate(aggregate)
|
||||
if not is_pass:
|
||||
@@ -348,6 +371,11 @@ class PartOf(Facet):
|
||||
if group.is_a().upper() != self.entity:
|
||||
is_pass = False
|
||||
reason = {"type": "ENTITY", "actual": group.is_a().upper()}
|
||||
if self.predefinedType:
|
||||
predefined_type = ifcopenshell.util.element.get_predefined_type(group)
|
||||
if predefined_type != self.predefinedType:
|
||||
is_pass = False
|
||||
reason = {"type": "PREDEFINEDTYPE", "actual": predefined_type}
|
||||
elif self.relation == "IfcRelContainedInSpatialStructure":
|
||||
container = ifcopenshell.util.element.get_container(inst)
|
||||
is_pass = container is not None
|
||||
@@ -357,6 +385,11 @@ class PartOf(Facet):
|
||||
if container.is_a().upper() != self.entity:
|
||||
is_pass = False
|
||||
reason = {"type": "ENTITY", "actual": container.is_a().upper()}
|
||||
if self.predefinedType:
|
||||
predefined_type = ifcopenshell.util.element.get_predefined_type(container)
|
||||
if predefined_type != self.predefinedType:
|
||||
is_pass = False
|
||||
reason = {"type": "PREDEFINEDTYPE", "actual": predefined_type}
|
||||
elif self.relation == "IfcRelNests":
|
||||
nest = self.get_nested_whole(inst)
|
||||
is_pass = nest is not None
|
||||
@@ -368,7 +401,11 @@ class PartOf(Facet):
|
||||
while nest is not None:
|
||||
ancestors.append(nest.is_a())
|
||||
if nest.is_a().upper() == self.entity:
|
||||
is_pass = True
|
||||
if self.predefinedType:
|
||||
if ifcopenshell.util.element.get_predefined_type(nest) == self.predefinedType:
|
||||
is_pass = True
|
||||
else:
|
||||
is_pass = True
|
||||
break
|
||||
nest = self.get_nested_whole(nest)
|
||||
if not is_pass:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!-- edited with XMLSpy v2022 (x64) (http://www.altova.com) by Leon van Berlo (Overleaf Investments B.V.) -->
|
||||
<!-- August 2, 2022 - DRAFT -->
|
||||
<xs:schema xmlns:ids="http://standards.buildingsmart.org/IDS" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" targetNamespace="http://standards.buildingsmart.org/IDS" elementFormDefault="qualified" attributeFormDefault="unqualified" version="0.9.0">
|
||||
<!-- edited with XMLSpy v2022 (x64) (http://www.altova.com) -->
|
||||
<!-- September 26, 2022 - DRAFT -->
|
||||
<xs:schema xmlns:ids="http://standards.buildingsmart.org/IDS" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" targetNamespace="http://standards.buildingsmart.org/IDS" elementFormDefault="qualified" attributeFormDefault="unqualified" version="0.9.3">
|
||||
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
|
||||
<xs:import namespace="http://www.w3.org/2001/XMLSchema" schemaLocation="https://www.w3.org/2001/XMLSchema.xsd"/>
|
||||
<xs:import namespace="http://www.w3.org/2001/XMLSchema-instance" schemaLocation="http://www.w3.org/2001/XMLSchema-instance"/>
|
||||
@@ -58,7 +58,7 @@
|
||||
</xs:complexType>
|
||||
<xs:complexType name="partOfType">
|
||||
<xs:sequence>
|
||||
<xs:element name="entity" type="ids:idsValue" minOccurs="0"/>
|
||||
<xs:element name="entity" type="ids:entityType" minOccurs="0"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="relation" type="ids:relations" use="required"/>
|
||||
</xs:complexType>
|
||||
@@ -198,7 +198,7 @@
|
||||
<xs:complexType name="specificationType">
|
||||
<xs:sequence>
|
||||
<xs:element name="applicability" type="ids:applicabilityType"/>
|
||||
<xs:element name="requirements">
|
||||
<xs:element name="requirements" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:complexContent>
|
||||
<xs:extension base="ids:requirementsType">
|
||||
@@ -248,4 +248,4 @@
|
||||
<xs:enumeration value="IfcRelNests"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:schema>
|
||||
</xs:schema>
|
||||
@@ -1404,13 +1404,17 @@ class TestPartOf:
|
||||
assert facet.asdict() == {"@relation": "IfcRelAggregates"}
|
||||
facet = PartOf(
|
||||
entity="IfcGroup",
|
||||
predefinedType="predefinedType",
|
||||
relation="IfcRelAssignsToGroup",
|
||||
minOccurs="0",
|
||||
maxOccurs="unbounded",
|
||||
instructions="instructions",
|
||||
)
|
||||
assert facet.asdict() == {
|
||||
"entity": {"simpleValue": "IfcGroup"},
|
||||
"entity": {
|
||||
"name": {"simpleValue": "IfcGroup"},
|
||||
"predefinedType": {"simpleValue": "predefinedType"},
|
||||
},
|
||||
"@relation": "IfcRelAssignsToGroup",
|
||||
"@minOccurs": "0",
|
||||
"@maxOccurs": "unbounded",
|
||||
@@ -1446,6 +1450,12 @@ class TestPartOf:
|
||||
facet = PartOf(entity="IFCWALL", relation="IfcRelAggregates")
|
||||
run("An aggregate may specify the entity of the whole 2/2", facet=facet, inst=subelement, expected=False)
|
||||
|
||||
element.PredefinedType = "BASESLAB"
|
||||
facet = PartOf(entity="IFCSLAB", predefinedType="BASESLAB", relation="IfcRelAggregates")
|
||||
run("An aggregate may specify the predefined type of the whole 1/2", facet=facet, inst=subelement, expected=True)
|
||||
facet = PartOf(entity="IFCSLAB", predefinedType="SLABRADOR", relation="IfcRelAggregates")
|
||||
run("An aggregate may specify the predefined type of the whole 2/2", facet=facet, inst=subelement, expected=False)
|
||||
|
||||
ifc = ifcopenshell.file()
|
||||
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcElementAssembly")
|
||||
subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcSlab")
|
||||
@@ -1472,6 +1482,12 @@ class TestPartOf:
|
||||
facet = PartOf(entity="IFCINVENTORY", relation="IfcRelAssignsToGroup")
|
||||
run("A group entity must match exactly 2/2", facet=facet, inst=element, expected=True)
|
||||
|
||||
group.ObjectType = "BUNNY"
|
||||
facet = PartOf(entity="IFCINVENTORY", predefinedType="BUNNARY", relation="IfcRelAssignsToGroup")
|
||||
run("A group predefined type must match exactly 2/2", facet=facet, inst=element, expected=False)
|
||||
facet = PartOf(entity="IFCINVENTORY", predefinedType="BUNNY", relation="IfcRelAssignsToGroup")
|
||||
run("A group predefined type must match exactly 2/2", facet=facet, inst=element, expected=True)
|
||||
|
||||
ifc = ifcopenshell.file()
|
||||
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcElementAssembly")
|
||||
container = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcSpace")
|
||||
@@ -1490,6 +1506,12 @@ class TestPartOf:
|
||||
facet = PartOf(relation="IfcRelContainedInSpatialStructure", entity="IFCSPACE")
|
||||
run("The container entity must match exactly 2/2", facet=facet, inst=element, expected=True)
|
||||
|
||||
container.ObjectType = "BURROW"
|
||||
facet = PartOf(relation="IfcRelContainedInSpatialStructure", entity="IFCSPACE", predefinedType="WARREN")
|
||||
run("The container predefined type must match exactly 1/2", facet=facet, inst=element, expected=False)
|
||||
facet = PartOf(relation="IfcRelContainedInSpatialStructure", entity="IFCSPACE", predefinedType="BURROW")
|
||||
run("The container predefined type must match exactly 2/2", facet=facet, inst=element, expected=True)
|
||||
|
||||
ifc = ifcopenshell.file()
|
||||
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcSlab")
|
||||
subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcBeam")
|
||||
@@ -1516,6 +1538,12 @@ class TestPartOf:
|
||||
facet = PartOf(relation="IfcRelNests", entity="IFCFURNITURE")
|
||||
run("The nest entity must match exactly 2/2", facet=facet, inst=subelement, expected=True)
|
||||
|
||||
element.ObjectType = "WATERBOTTLE"
|
||||
facet = PartOf(relation="IfcRelNests", entity="IFCFURNITURE", predefinedType="LITTERBOX")
|
||||
run("The nest predefined type must match exactly 1/2", facet=facet, inst=subelement, expected=False)
|
||||
facet = PartOf(relation="IfcRelNests", entity="IFCFURNITURE", predefinedType="WATERBOTTLE")
|
||||
run("The nest predefined type must match exactly 2/2", facet=facet, inst=subelement, expected=True)
|
||||
|
||||
ifc = ifcopenshell.file()
|
||||
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcFurniture")
|
||||
subelement = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcDiscreteAccessory")
|
||||
|
||||
Reference in New Issue
Block a user