mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-24 21:50:01 +00:00
IfcTester Add support for qto checks
This commit is contained in:
@@ -443,7 +443,9 @@ class Property(Facet):
|
|||||||
if isinstance(self.name, str):
|
if isinstance(self.name, str):
|
||||||
prop = pset_props.get(self.name)
|
prop = pset_props.get(self.name)
|
||||||
if prop == "UNKNOWN" and [
|
if prop == "UNKNOWN" and [
|
||||||
p for p in inst.wrapped_data.file.by_id(pset_props["id"]).HasProperties if p.Name == self.name
|
p
|
||||||
|
for p in self.get_properties(inst.wrapped_data.file.by_id(pset_props["id"]))
|
||||||
|
if p.Name == self.name
|
||||||
][0].NominalValue.is_a("IfcLogical"):
|
][0].NominalValue.is_a("IfcLogical"):
|
||||||
pass
|
pass
|
||||||
elif prop is not None and prop != "":
|
elif prop is not None and prop != "":
|
||||||
@@ -457,30 +459,49 @@ class Property(Facet):
|
|||||||
break
|
break
|
||||||
|
|
||||||
pset_entity = inst.wrapped_data.file.by_id(pset_props["id"])
|
pset_entity = inst.wrapped_data.file.by_id(pset_props["id"])
|
||||||
for prop_entity in pset_entity.HasProperties:
|
|
||||||
if (
|
|
||||||
prop_entity.Name not in props[pset_name].keys()
|
|
||||||
or not prop_entity.is_a("IfcPropertySingleValue")
|
|
||||||
or prop_entity.NominalValue is None
|
|
||||||
):
|
|
||||||
continue
|
|
||||||
|
|
||||||
data_type = prop_entity.NominalValue.is_a()
|
for prop_entity in self.get_properties(pset_entity):
|
||||||
|
if prop_entity.is_a("IfcPropertySingleValue"):
|
||||||
|
if prop_entity.Name not in props[pset_name].keys() or prop_entity.NominalValue is None:
|
||||||
|
continue
|
||||||
|
|
||||||
if data_type != self.measure:
|
data_type = prop_entity.NominalValue.is_a()
|
||||||
is_pass = False
|
|
||||||
reason = {"type": "MEASURE", "actual": data_type}
|
|
||||||
break
|
|
||||||
|
|
||||||
unit = ifcopenshell.util.unit.get_property_unit(prop_entity, inst.wrapped_data.file)
|
if data_type != self.measure:
|
||||||
if unit:
|
is_pass = False
|
||||||
props[pset_name][prop_entity.Name] = ifcopenshell.util.unit.convert(
|
reason = {"type": "MEASURE", "actual": data_type}
|
||||||
prop_entity.NominalValue.wrappedValue,
|
break
|
||||||
getattr(unit, "Prefix", None),
|
|
||||||
unit.Name,
|
unit = ifcopenshell.util.unit.get_property_unit(prop_entity, inst.wrapped_data.file)
|
||||||
None,
|
if unit:
|
||||||
ifcopenshell.util.unit.si_type_names[unit.UnitType],
|
props[pset_name][prop_entity.Name] = ifcopenshell.util.unit.convert(
|
||||||
)
|
prop_entity.NominalValue.wrappedValue,
|
||||||
|
getattr(unit, "Prefix", None),
|
||||||
|
unit.Name,
|
||||||
|
None,
|
||||||
|
ifcopenshell.util.unit.si_type_names[unit.UnitType],
|
||||||
|
)
|
||||||
|
elif prop_entity.is_a("IfcPhysicalSimpleQuantity"):
|
||||||
|
if prop_entity.Name not in props[pset_name].keys():
|
||||||
|
continue
|
||||||
|
|
||||||
|
prop_schema = prop_entity.wrapped_data.declaration().as_entity()
|
||||||
|
data_type = prop_schema.attribute_by_index(3).type_of_attribute().declared_type().name()
|
||||||
|
|
||||||
|
if data_type != self.measure:
|
||||||
|
is_pass = False
|
||||||
|
reason = {"type": "MEASURE", "actual": data_type}
|
||||||
|
break
|
||||||
|
|
||||||
|
unit = ifcopenshell.util.unit.get_property_unit(prop_entity, inst.wrapped_data.file)
|
||||||
|
if unit:
|
||||||
|
props[pset_name][prop_entity.Name] = ifcopenshell.util.unit.convert(
|
||||||
|
prop_entity[3],
|
||||||
|
getattr(unit, "Prefix", None),
|
||||||
|
unit.Name,
|
||||||
|
None,
|
||||||
|
ifcopenshell.util.unit.si_type_names[unit.UnitType],
|
||||||
|
)
|
||||||
|
|
||||||
if not is_pass:
|
if not is_pass:
|
||||||
break
|
break
|
||||||
@@ -512,6 +533,14 @@ class Property(Facet):
|
|||||||
return PropertyResult(not is_pass, {"type": "PROHIBITED"})
|
return PropertyResult(not is_pass, {"type": "PROHIBITED"})
|
||||||
return PropertyResult(is_pass, reason)
|
return PropertyResult(is_pass, reason)
|
||||||
|
|
||||||
|
def get_properties(self, pset):
|
||||||
|
if pset.is_a("IfcPropertySet"):
|
||||||
|
return pset.HasProperties
|
||||||
|
elif pset.is_a("IfcElementQuantity"):
|
||||||
|
return pset.Quantities
|
||||||
|
elif pset.is_a("IfcMaterialProperties") or pset.is_a("IfcProfileProperties"):
|
||||||
|
return pset.Properties
|
||||||
|
|
||||||
|
|
||||||
class Material(Facet):
|
class Material(Facet):
|
||||||
def __init__(self, value=None, uri=None, minOccurs=None, maxOccurs=None, instructions=None):
|
def __init__(self, value=None, uri=None, minOccurs=None, maxOccurs=None, instructions=None):
|
||||||
|
|||||||
@@ -881,6 +881,10 @@ class TestProperty:
|
|||||||
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"})
|
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"})
|
||||||
run("A name check will match any property with any string value", facet=facet, inst=element, expected=True)
|
run("A name check will match any property with any string value", facet=facet, inst=element, expected=True)
|
||||||
|
|
||||||
|
facet = Property(propertySet="Foo_Bar", name="Foo", measure="IfcLabel")
|
||||||
|
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
|
||||||
|
pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar")
|
||||||
|
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"})
|
||||||
run("A required facet checks all parameters as normal", facet=facet, inst=element, expected=True)
|
run("A required facet checks all parameters as normal", facet=facet, inst=element, expected=True)
|
||||||
facet = Property(propertySet="Foo_Bar", name="Foo", measure="IfcLabel", minOccurs=0, maxOccurs=0)
|
facet = Property(propertySet="Foo_Bar", name="Foo", measure="IfcLabel", minOccurs=0, maxOccurs=0)
|
||||||
run("A prohibited facet returns the opposite of a required facet", facet=facet, inst=element, expected=False)
|
run("A prohibited facet returns the opposite of a required facet", facet=facet, inst=element, expected=False)
|
||||||
@@ -1005,6 +1009,14 @@ class TestProperty:
|
|||||||
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcDuration("P2D")})
|
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcDuration("P2D")})
|
||||||
run("Durations are treated as strings 1/2", facet=facet, inst=element, expected=False)
|
run("Durations are treated as strings 1/2", facet=facet, inst=element, expected=False)
|
||||||
|
|
||||||
|
facet = Property(propertySet="Foo_Bar", name="Foo", measure="IfcLengthMeasure")
|
||||||
|
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
|
||||||
|
qto = ifcopenshell.api.run("pset.add_qto", ifc, product=element, name="Foo_Bar")
|
||||||
|
ifcopenshell.api.run("pset.edit_qto", ifc, qto=qto, properties={"Foo": ifc.createIfcLengthMeasure(42)})
|
||||||
|
run("A name check will match any quantity with any value", facet=facet, inst=element, expected=True)
|
||||||
|
facet = Property(propertySet="Foo_Bar", name="Foo", measure="IfcAreaMeasure")
|
||||||
|
run("Quantities must also match the appropriate measure", facet=facet, inst=element, expected=False)
|
||||||
|
|
||||||
restriction = Restriction(options="Foo_.*", type="pattern")
|
restriction = Restriction(options="Foo_.*", type="pattern")
|
||||||
facet = Property(propertySet=restriction, name="Foo", measure="IfcLabel")
|
facet = Property(propertySet=restriction, name="Foo", measure="IfcLabel")
|
||||||
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
|
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
|
||||||
@@ -1288,7 +1300,9 @@ class TestPartOf:
|
|||||||
run("The aggregated part passes an aggregate relationship", facet=facet, inst=subelement, expected=True)
|
run("The aggregated part passes an aggregate relationship", facet=facet, inst=subelement, expected=True)
|
||||||
|
|
||||||
run("A required facet checks all parameters as normal", facet=facet, inst=subelement, expected=True)
|
run("A required facet checks all parameters as normal", facet=facet, inst=subelement, expected=True)
|
||||||
|
facet = PartOf(relation="IfcRelAggregates", minOccurs=0, maxOccurs=0)
|
||||||
run("A prohibited facet returns the opposite of a required facet", facet=facet, inst=subelement, expected=False)
|
run("A prohibited facet returns the opposite of a required facet", facet=facet, inst=subelement, expected=False)
|
||||||
|
facet = PartOf(relation="IfcRelAggregates", minOccurs=0)
|
||||||
run("An optional facet always passes regardless of outcome 1/2", facet=facet, inst=element, expected=True)
|
run("An optional facet always passes regardless of outcome 1/2", facet=facet, inst=element, expected=True)
|
||||||
run("An optional facet always passes regardless of outcome 2/2", facet=facet, inst=subelement, expected=True)
|
run("An optional facet always passes regardless of outcome 2/2", facet=facet, inst=subelement, expected=True)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user