mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 02:47:48 +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):
|
||||
prop = pset_props.get(self.name)
|
||||
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"):
|
||||
pass
|
||||
elif prop is not None and prop != "":
|
||||
@@ -457,30 +459,49 @@ class Property(Facet):
|
||||
break
|
||||
|
||||
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:
|
||||
is_pass = False
|
||||
reason = {"type": "MEASURE", "actual": data_type}
|
||||
break
|
||||
data_type = prop_entity.NominalValue.is_a()
|
||||
|
||||
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.NominalValue.wrappedValue,
|
||||
getattr(unit, "Prefix", None),
|
||||
unit.Name,
|
||||
None,
|
||||
ifcopenshell.util.unit.si_type_names[unit.UnitType],
|
||||
)
|
||||
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.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:
|
||||
break
|
||||
@@ -512,6 +533,14 @@ class Property(Facet):
|
||||
return PropertyResult(not is_pass, {"type": "PROHIBITED"})
|
||||
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):
|
||||
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"})
|
||||
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)
|
||||
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)
|
||||
@@ -1005,6 +1009,14 @@ class TestProperty:
|
||||
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)
|
||||
|
||||
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")
|
||||
facet = Property(propertySet=restriction, name="Foo", measure="IfcLabel")
|
||||
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("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)
|
||||
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 2/2", facet=facet, inst=subelement, expected=True)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user